Skip to content

Repository files navigation

Takeover Loop (T-O)

Hand Claude a goal, walk away, come back to verified work.

A Claude Code skill that turns one session into two Claudes working as a team: an executive supervisor that sits in your seat, and a separate headless daemon (claude -p, its own process, its own context) that does the work in cycles. Each cycle the daemon reports; the supervisor re-runs the gates itself, answers the daemon's questions on your behalf, and resumes it with the next orders — until the goal is met or a ceiling trips.

You are interrupted only for decisions that are genuinely yours.

This spawns a real background process that spends real money and edits real files. Read Safety before your first run. There is a hard cost cap, a hard cycle cap, and a one-command kill switch — all three are mandatory by design.


Contents

Why · How it works · Install · Quickstart · Modes · What it creates · Configuration · Safety · Cost · Compatibility · Field notes · Troubleshooting · Uninstall


Why this exists

Long autonomous runs fail in three predictable ways. This skill is built around preventing exactly those three:

Failure What this does about it
The loop quits early and looks finished — the common one The skill's first law is that its default state is running. Obstacles are work, not exits: a denied tool, a failing gate, a blocked deliverable all mean route around and keep going. It stops when the goal is verified done or you say stop.
The agent says "done" and it isn't The supervisor never accepts a claim. It re-runs the gates itself and records what it actually saw.
The loop stalls overnight waiting for a human The supervisor answers routine questions in your voice and parks only genuinely owner-level decisions (ship, spend, legal) — then carries on with everything else.
The loop runs forever and burns money Cost and cycle brakes, plus a STOP sentinel. Hitting a brake is a prompt to raise it, not the end of the run; you get a warning at 80% so it is never an ambush.

Once you invoke it, Claude stops behaving like an assistant answering turns and becomes the Operator: it holds your authority, runs the build team, and is accountable for the goal reaching done. That identity is re-anchored from .takeover/OPERATOR.md at the top of every cycle, so it survives the context compaction that would otherwise make it drift back into asking permission.

How it works

  you ──plan & ceilings──►  SUPERVISOR (this Claude, your session)
                                 │  ▲
                    spawn/resume │  │ report: DONE / EVIDENCE /
                    with orders  │  │ DECISIONS NEEDED / NEXT CYCLE
                                 ▼  │
                            DAEMON (claude -p, separate process)
                                 │
                                 ├── edits code, runs tests, commits
                                 └── may fan out to its own subagents

  after every cycle the supervisor:
    1. re-runs the gates ITSELF            (a claim is not evidence)
    2. decides, or parks for you           (reversible+in-scope vs owner-only)
    3. writes .takeover/  state to disk    (survives compaction and crashes)
    4. resumes the daemon, or stops

The two-tier split is the point. The daemon has the working context and does the building; the supervisor has fresh eyes, the gates, and the authority — so the agent doing the work is never the one grading it.

Install

Skills install per user or per project. There is no supported way for a public repo to install a skill for every user of a machine — device-wide deployment requires an administrator-managed settings file and is an IT deployment model, not an install command. See device-wide.

Option A — plugin (recommended)

Versioned, updatable, uninstallable. Works the same on Windows, macOS, and Linux.

claude plugin marketplace add AbdulrahmanAmer/takeover-loop
claude plugin install takeover-loop@takeover-loop --scope user

Or from inside a session: /plugin marketplace add AbdulrahmanAmer/takeover-loop then /plugin install takeover-loop@takeover-loop.

Update later with claude plugin update takeover-loop.

Option B — one-line installer

Copies the skill into ~/.claude/skills/. No plugin system required.

macOS / Linux:

curl -fsSL https://raw.githubusercontent.com/AbdulrahmanAmer/takeover-loop/main/install.sh | bash

Windows PowerShell:

irm https://raw.githubusercontent.com/AbdulrahmanAmer/takeover-loop/main/install.ps1 | iex

Both accept --project / -Project to install into ./.claude/skills/ instead, which is what you want if you're committing the skill so teammates and cloud sessions get it.

Option C — manual

git clone https://github.com/AbdulrahmanAmer/takeover-loop
cp -r takeover-loop/skills/takeover-loop ~/.claude/skills/
cp -r takeover-loop/skills/t-o          ~/.claude/skills/   # optional /t-o alias

Restart Claude Code if ~/.claude/skills/ did not already exist.

Device-wide (for administrators)

Only via managed settings, which needs admin/root:

OS Path
Windows C:\ProgramData\ClaudeCode\managed-settings.json
macOS /Library/Application Support/ClaudeCode/managed-settings.json
Linux /etc/claude-code/managed-settings.json

Quickstart

Just say it:

T-O — get the test suite passing and refactor anything over 400 lines

or take over, you drive, run this autonomously, or /t-o.

What happens first is a conversation, not a spawn. It asks which mode to run, then plans the cycles with you, proposes gates, and asks for the ceilings and authority profile. Then it asks for an explicit go. That exchange is the safety mechanism — it is not skippable, and a skill that spawned immediately would be a worse one.

After that it does not stop to check in: preflight → spawn → cycles, verifying each one, deciding what's its to decide and parking what's yours — until the goal is verified done or you say stop. Then a final report with a numbered punch-list of everything it left for you.

Modes — who does which job

The first thing it asks, before any planning: how hard do you want to run this? The answer changes cost by an order of magnitude, so it's yours to pick, not the skill's to assume.

Role lab — default max
Orchestrator best:ultracode best:ultracode
Research / discovery haiku best:high
Build / implementation sonnet:medium best:high
Mechanical / batch edits haiku best:medium
Adversarial verification opus:high best:xhigh

lab is how research labs actually run it, and the right answer most of the time: expensive judgment, cheap breadth. A strong orchestrator plans, judges and synthesises; the cheapest model that can genuinely do each task does it; verification stays expensive, because a cheap verifier that confirms everything is worse than none. This is the mode that works on a smaller subscription or an API budget.

max puts everything on the strongest tier. Right when a weak link costs more than tokens do — one-shotting a large, fully-specified plan with no research phase. It is not "better" in general; it's more expensive for the same result on tasks a smaller model does just as well.

custom walks you through model and effort per role.

to.sh init --mode lab --max-usd 100 --max-cycles 12          # default
to.sh init --mode max --max-usd 400 --max-cycles 8           # one-shot a big plan
to.sh init --mode custom --model opus --effort xhigh \
  --role research=haiku --role build=sonnet:high --role verify=fable:xhigh

Explicit flags always beat the mode — --mode lab --role build=opus:high is a lab run with a stronger builder. to.sh plan prints the live routing so you can check it before anything spawns.

Honest about these defaults. They're grounded in documented model capability and published cost — which models support which effort levels, which have none, which have extended context. They are not benchmark output, and this repo doesn't claim they're optimal for your workload. --role exists so you can override them; if you measure something better, that's worth an issue.

Full detail, including the custom question set: modes.md.

What it creates

Everything lives in .takeover/ at your project root, gitignored automatically:

File Holds
config.env session UUID, ceilings, model, effort, profile
charter.md the goal and exit criteria, written once at plan time
worklog.md per cycle: what was claimed vs what the supervisor verified
punchlist.md owner-only decisions, numbered, each with a recommendation
gates.sh / gates.ps1 the deterministic checks you agreed to
daemon-settings.json the deny list that blocks pushes, deploys, and secret reads
spend.txt cumulative cost ledger across cycles
STOP create this and the loop halts at the next cycle boundary
cycles/NN.* full audit trail: prompt, JSON report, stderr

This is what lets a run survive the supervisor's context compacting, your terminal closing, or a reboot. State on disk, never in a model's head.

Configuration

Set at init, stored in .takeover/config.env:

Option Meaning
--mode lab (default), max, custom. Sets the whole routing table. See Modes.
--role research=/build=/mechanical=/verify= as model[:effort]. Repeatable; overrides the mode. A bare model leaves effort unset — required for Haiku.
--max-usd required. Runaway brake on total spend — not a target. Pass none to run uncapped (a deliberate opt-out, never the default).
--max-cycles required. Runaway brake on cycle count. none to run uncapped.
--per-cycle-usd Per-invocation cap, passed to --max-budget-usd. Set this generously — when it trips it kills the cycle mid-work, losing uncommitted progress.
--model / --effort Orchestrator only. Overrides the mode's choice.
--profile fenced, standard (default), open. See Safety.
--fallback-model Survives an overloaded primary. Worth it for overnight runs.
--add-dir Extra directories the daemon may access.

Manual control at any time. The launcher path depends on how you installed:

Install Launcher path
Installer / manual (user) ~/.claude/skills/takeover-loop/scripts/to.sh
Installer / manual (project) ./.claude/skills/takeover-loop/scripts/to.sh
Plugin inside the plugin cache, not ~/.claude/skills — find it with claude plugin details takeover-loop
TO=~/.claude/skills/takeover-loop/scripts/to.sh   # adjust per the table above

bash "$TO" plan     # print the exact command, run nothing
bash "$TO" status   # cycle, spend, is a daemon alive
bash "$TO" stop     # STOP sentinel + kill anything in flight

On Windows use to.ps1 with the same verbs (& "$TO" status).

plan is worth running before your first spawn. It prints the exact command that would execute, and tells you in plain terms whether MCP servers are reachable and how many deny rules are active — so you can see the fencing before an unattended process uses it, not after.

Safety

The daemon runs unattended with reduced permission prompts. That is the feature and the risk. Three authority profiles:

Profile What the daemon gets Use when
fenced --permission-mode acceptEdits — file edits automatic, other shell commands denied Untrusted repo or shared machine. Safest, but denied work is skipped silently — read permission_denials.
standard (default) Full bypass plus a deny list plus --strict-mcp-config A disposable worktree on your own machine.
open Full bypass, nothing fenced Disposable container/VM only. Never with production access.

What standard mechanically blocks — not by asking nicely, but via a --settings deny list re-passed on every cycle:

  • git push, git remote add/set-url/remove
  • npm/yarn/pnpm publish, gh release, gh pr merge, gh secret, gh repo delete
  • deploy and cloud CLIs: Netlify, Vercel, Wrangler, AWS, gcloud, az, kubectl apply, terraform apply/destroy, docker push
  • sudo, shutdown, reboot
  • Write/Edit to .git/**, .github/workflows/**, and Claude settings files
  • reads of .env*, *.pem, id_rsa*, and ~/.ssh, ~/.aws, .npmrc, .netrc

What is deliberately NOT blocked: everyday tooling. npx, package runners, test drivers, curl, bash -c, build tools all run freely. An earlier version blocked npx to close a wrapper-bypass — which meant the daemon could not run its own test gate, reported the denial, and the run died with the goal half-finished. A deny list that stops the work is a broken deny list. Verified: npx runs, git push is refused.

Be clear about what this is. Bash rules are prefix matches, so this stops accidents and honest mistakes, not a determined agent. The real controls are the disposable worktree, --strict-mcp-config, and your per-cycle review. For untrusted code, use a container.

Plus --strict-mcp-config, so the daemon does not inherit your configured MCP servers. For most working developers those include live database, hosting, and DNS credentials, and an unattended process has no business holding them.

Threat model, stated plainly: the daemon reads files and possibly the web, then acts on what it reads with no human approving each step. That is a prompt-injection path to code execution. A string in a dependency README, an issue body, or a test fixture that reads like an instruction can be acted on. Mitigations in order of effectiveness: a disposable worktree, --strict-mcp-config, the deny list, your per-cycle review, and a container for anything genuinely untrusted.

Also worth knowing:

  • --dangerously-skip-permissions is refused as root/sudo. Docker and CI users hit this on the first command. Run as non-root, or use fenced.
  • Review the deny list against your repo. A custom make ship target isn't in the defaults, and the defaults cannot know about it.
  • .takeover/ holds raw daemon output in plaintext. Delete it after a sensitive run.

Cost

Be ready for the real numbers. Measured on CLI 2.1.220: a claude -p run whose entire job was to reply OK cost $0.03 — trivial prompt, but the session still loads tens of thousands of tokens of context. A real cycle that reads a codebase, edits files, and runs a suite costs meaningfully more; a cycle that fans out to subagents multiplies it again.

So: --max-usd and --max-cycles are mandatory, the supervisor reports spend against the cap at every check-in, and the launcher hard-refuses to start a cycle once the ledger trips. Note that --max-budget-usd caps a single invocation — the cumulative ledger in .takeover/spend.txt is what enforces the run-level cap.

Subscription plans have usage windows. A heavy loop can exhaust one; that's a stop condition, not something to retry through.

Compatibility

Verified against Claude Code CLI 2.1.220. Works on any model — it picks the highest tier your model and CLI actually support:

Tier Requires Launch
1 CLI ≥ 2.1.203, xhigh-capable model, workflows on --effort ultracode
2 xhigh-capable model --effort xhigh + Agent-tool fan-out
3 effort but no xhigh (Opus/Sonnet 4.6) --effort high
4 Haiku — no effort support omit --effort, smaller cycles
5 no subagents single-context sequential loop

One finding worth publishing on its own. Putting the word ultracode in a prompt piped to claude -p does nothing. Verified three ways: asking a headless run whether the orchestration reminder is in its context returns ABSENT for a plain run and ABSENT with the keyword in the prompt, but PRESENT with --effort ultracode. The keyword only opts in for human-typed input; -p is excluded. The Workflow tool is in the tool list either way, so there's no error — the daemon just never orchestrates. If you've been putting ultracode in headless prompts, it has been a silent no-op. Use the launch flag.

Requires git (progress detection and rollback depend on it) and either bash or PowerShell. No Node, Python, or jq needed.

Troubleshooting

Symptom Fix
Child dies instantly, OAuth error You must run claude auth login yourself — a headless child cannot do a browser login.
Refused, message mentions root/sudo Run as non-root, or use --profile fenced. No override exists.
Unknown --effort value CLI older than 2.1.203. Use --effort xhigh.
No conversation found with session ID Resume is scoped to the creating directory. Run every cycle from the same worktree.
Cycle exits 0 and "succeeds" but nothing happened Headless runs never stall on a permission prompt — they deny and continue. Check permission_denials in the report; a flag was probably dropped on resume. Use the launcher: resume restores neither permission mode nor --settings.
Exit 0 but the report reads mid-work It ended its turn with pending background work; in headless mode turn-end is process-end. Resume and require foreground/tracked work.
Every gate green on hard work Suspect the gate, not the daemon. Break something and confirm it goes red.

Full table: failure-modes.md.

Uninstall

claude plugin uninstall takeover-loop          # plugin install
rm -rf ~/.claude/skills/takeover-loop ~/.claude/skills/t-o   # manual install
rm -rf .takeover                               # a project's run state

Field notes — what was broken and how it was found

FIELD-NOTES.md is the honest engineering record: every defect found while making this publishable, why it happened, and how it was caught. It is probably more useful than the skill itself if you are building an agent harness of your own.

Highlights, all verified by running them rather than reading docs:

  • A keyword that had been a silent no-op — the mechanism the original skill credited for its results was switched off the whole time.
  • Two environment variables with zero occurrences in the binary, published as general mechanism.
  • Headless runs never stall on a permission prompt — they deny and continue, exiting 0 with subtype: success having done nothing. The failure that looks exactly like success.
  • Safety hardening that killed the loop: blocking npx to close a bypass also blocked the daemon's own test runner, and a real run died at cycle 7 of 10 with budget unspent.
  • Cross-platform defects invisible from one machine: a PowerShell exit code that was always 0, a spend ledger that silently reset to zero on comma-decimal locales, CRLF shipping into to.sh.
  • Several defects introduced by the fix for an earlier defect — including a config-injection guard that guarded nothing.

Contributing

Every factual claim about the CLI in this repo is meant to be verifiable against claude --help or a live run. If you find one that isn't, that's a bug worth an issue — that failure mode is exactly what the original version of this skill got wrong.

MIT licensed.

About

Supervised autonomous loop for Claude Code: one Claude supervises, a headless claude -p daemon does the work in verify-then-resume cycles — with hard cost/cycle ceilings, mechanical gates, and a real kill switch.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages