agentleFS
axiomanticaxiomantic/spellbook/skills/autonomous-mode/SKILL.md

autonomous-mode

Skill11 starsChanged 3 months agoMITView on GitHub

Use when the operator asks for unattended work. Triggers: 'work autonomously', 'fully autonomous', \"don't stop unless you have a blocker\", 'keep going until it's done', 'don't check in with me', 'run until finished', 'no need to ask, just do it'. NOT for: a single unattended command, YOLO/permission-bypass questions (that is tool approval, not turn-end enforcement), or ending a session already in autonomous mode (the operator's escape phrase does that).

We split this skill into the rules it gives an agent

2 rules. About 0 are common, 0 are distinctive, and 2 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈0

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Ask through AskUserQuestion, in one batch:

    line 35
  2. Very specific:

    Before continuing with the work: status exited 0 for this session.

    line 120

≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Autonomous Mode

<ROLE> You are the gatekeeper of an enforcement mechanism, not a motivational setting. Your job is to make the operator's authority explicit, write it down, and state honestly what the mechanism does and does not guarantee. You do not start the work from here. </ROLE>

<BEHAVIORAL_MODE> ENTRY GATE: ask, record, then continue with the actual request. Never enable autonomous mode by inference from phrasing alone, and never write the record without the operator's answers. </BEHAVIORAL_MODE>

Invariant Principles

  1. The record is the mode. Autonomous mode is the file spellbook/core/autonomous.py writes, not a statement in the transcript. No record, no enforcement — the Stop hook allows every turn-end it cannot attribute to a record. So the record is written through the helper below and then READ BACK; an unverified write leaves a mode that is on in the transcript and off in the mechanism.
  2. Ask before recording. Mode and philosophy come from the operator through AskUserQuestion. Standing autonomous phrasing is the trigger for this question, never its answer.
  3. The goal is captured in the operator's words. The Stop handler quotes it back on every refusal, so a session that has lost the thread is reminded what it is for.
  4. The exit belongs to the operator. Nothing the agent does ends autonomous mode. Say so when you enable it.
  5. State the limits when you sell the mechanism. The guarantees below are part of the offer, not fine print disclosed after a failure.

Reasoning Schema

<analysis>Before asking: state what the operator's request appears to scope, and what would count as its completion.</analysis> <reflection>After writing: confirm the record exists, and that the operator has been told the exit and the limits.</reflection>


The Gate

Ask through AskUserQuestion, in one batch:

Question 1 — how much decision authority?

AnswerWhat it means
fullyDecisions are yours wherever a reasonable default exists. An unattended decision is APPENDED to the record's decisions list — with the philosophy id active at that moment — instead of announced in the turn.
mostlyGenuine forks still come back to the operator through AskUserQuestion.
<CRITICAL> Both modes are held by exactly the same gate. The difference is how much reaches `AskUserQuestion` in the first place — NOT whether the `Stop` hook binds. `mostly` is not a softer gate; it is a chattier agent behind the identical gate. </CRITICAL>

Question 2 — which guiding philosophy?

Offer the ids the helper prints, each with the one-line meaning recorded beside it, and recommend the default it names. Read them at ask time; do not restate them here or in the question's own prose — a second copy of that list will drift from the one the hook names in its block messages.

python3 "$SPELLBOOK_DIR/skills/autonomous-mode/scripts/autonomous_mode.py" philosophies

Then capture the goal in the operator's own words and write the record:

python3 "$SPELLBOOK_DIR/skills/autonomous-mode/scripts/autonomous_mode.py" enable \
  --mode fully --philosophy build-right --goal "the operator's words here"

The session id is $CLAUDE_CODE_SESSION_ID, which the helper reads itself; pass --session-id only when it is unset. enable reads the record back and prints it, and exits non-zero if it did not land. Branch on the exit code, not on the output. If it is non-zero, tell the operator plainly that autonomous mode is NOT enabled and what the message said — do not proceed as though it were.

ExitMeaning
0done, verified against the record itself
1failed; the reason is on stderr
2usage error
3status only: this session is not autonomous

Confirm at any later point, and after any doubt:

python3 "$SPELLBOOK_DIR/skills/autonomous-mode/scripts/autonomous_mode.py" status

In fully mode, append each unattended decision instead of announcing it:

python3 "$SPELLBOOK_DIR/skills/autonomous-mode/scripts/autonomous_mode.py" decide \
  --decision "what you chose" --alternatives "what you did not choose, and why"

The philosophy id active at that moment is copied in for you. This log is the only behavioural difference between fully and mostly; a fully session that never calls decide is a mostly session.

clear exists for cleanup after completion. It is NOT the operator's exit — that is the escape phrase, and Principle 4 stands.


What Binds, Once Recorded

The Stop handler in hooks/spellbook_hook.py refuses a turn-end and hands the question back: are you DONE with the whole project goal, were you asked to PAUSE, or do you have a GENUINE BLOCKER? A long session, a finished list item, a returned subagent result, and a phase boundary are none of the three. On a genuine blocker the answer is AskUserQuestion, which is answered inline — it is not a turn-end.

The hook decides nothing about the work — it cannot, and it no longer pretends to. It kicks the session; the model answers by acting. Continuing IS the answer "I was not done". Ending the turn again is the answer "I was", and three of those inside the rolling window release the session.

What This Does NOT Guarantee

<CRITICAL> Tell the operator all of this when you enable the mode.
  • Nothing verifies that the work is done. The hook does not read the transcript, a gate ledger, or any evidence artifact; it cannot tell a finished project from an abandoned one. What it buys is that ending a turn takes insisting, which a session drifting toward an early stop will not do. Do not describe it to the operator as a completeness check.
  • The escape phrases are the operator's exit, matched case-insensitively as a substring of the prompt. Quote them to the operator verbatim from AUTONOMOUS_ESCAPE_PHRASES in hooks/spellbook_hook.py; never retype them from memory into prose that can drift from the recognizer.
  • A thrashing session is released. Repeated blocks inside a short rolling window open a valve and the next turn-end is ALLOWED — autonomous mode does not hold a session that is ending turns without doing work. The window and the limit are BLOCK_WINDOW_SECONDS and BLOCK_WINDOW_LIMIT in spellbook/core/autonomous.py; that valve is also the only loop stop there is.
  • The harness block cap is disabled by spellbook's installer. CLAUDE_CODE_STOP_HOOK_BLOCK_CAP is written to 0 by installer/components/hooks.py; on a machine without those settings the harness stops honoring the hook after its default number of consecutive blocks and ends the turn regardless. A cap the operator set to some other value is left alone, and the installer says so in its own output for that run.</CRITICAL>

Inputs

  • The operator's request, and the phrasing that triggered this skill.
  • The session id, which scopes the record; autonomy never outlives the conversation that granted it. It comes from $CLAUDE_CODE_SESSION_ID, the same source commands/a2a.md uses, and the helper reads it directly.

Outputs

  • A record written for this session AND read back through status, or an explicit statement that autonomous mode was NOT enabled.
  • A stated goal, the chosen mode and philosophy id, the exit phrases, and the limits above.

Self-Check

Before continuing with the work: status exited 0 for this session; the operator has the exit phrases; the limits were stated, not implied.

<FORBIDDEN> - Enabling autonomous mode without the operator's answers, or inferring mode or philosophy from the request. - Reporting autonomous mode as enabled on a non-zero exit, or without reading the record back. - Improvising a call into `spellbook.core.autonomous` instead of invoking the helper. A guessed interpreter or a guessed session id writes no record the hook will find, and an unwired autonomous mode looks exactly like a disabled one. - Recording a session with no stated goal. - Restating the philosophy meanings, the escape-phrase literals, or the valve's numbers in this file instead of pointing at the code that owns them. - Describing the `Stop` gate as a check on whether the work is complete. It refuses a turn-end; it verifies nothing. - Treating `mostly` as a weaker Stop gate, or clearing the record on the agent's own initiative. </FORBIDDEN>

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

Reviews can't be read right now.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.