Field Manual / Guide

Kill switch for an AI agent

A kill switch for an AI agent is a stop condition plus a mechanism outside the model that enforces it. Five mechanisms work: a process or session kill, a hook that blocks the tool call, an approval gate before side effects, a turn or budget cap, and revoking the credential. Fire each on a harmless run before trusting it.

By · Published · Updated

Last verified

Every harness has an interrupt key. Fewer have a kill switch. The difference is whether you have fired it and watched what stopped.

Chapter one says know how to cancel a run before you need to. Here is how: five mechanisms, a test for each, one logged burn. Every flag and key for all four mounts sits in one table on the comparison page; this page is about firing them.

What is a kill switch for an AI agent?

A kill switch is a stop condition plus a mechanism outside the model that enforces it.

“Stop if you see X” in a prompt is a condition with no mechanism; Reins calls that an instruction, not enforcement. The vendors agree: Claude Code enforces permission rules outside the model (source); Cursor calls rule-based steering not a safety net (source). Both last verified 2026-10-16.

MechanismWhat it stopsWhat it does not stop
1. Process or session killThe run and its childrenRemote jobs, scheduled work, sent side effects
2. Tool-level hookOne matching call, or the loopCalls it never sees; runs with hooks off
3. Approval gateThe named side effect, until a person says yesAnything already auto-approved
4. Turn or budget capThe loop at the numberOvershoot past the cap
5. Credential revocationEvery action needing the tokenLocal writes; what already happened

Does killing the process stop the run?

Ending the process is the first and bluntest stop, and it works only if you hit the right one.

Interactive stop keys, last verified 2026-10-16:

MountKeyWhat it stopsSource
Claude CodeEscThe response or tool call mid-turn; work done so far is keptinteractive mode
Cursor (IDE)Cmd+Shift+BackspaceGeneration. Cmd+Backspace rejects changes; it does not cancelkeyboard shortcuts
Codex CLIEscThe active turn. Ctrl+C or /exit ends the sessionkeymap.rs, slash commands
Gemini CLICtrl+CThe current request. Ctrl+K kills the background shellkeyboard shortcuts

Headless is different. SIGTERM to claude -p exits 143. It kills the process tree of any running Bash command, runs only SessionEnd hooks and records no result; send SIGINT first for a clean end (source, last verified 2026-10-16). A finished turn can still wait on background work for 10 minutes by default (source). codex exec turns Ctrl+C into turn/interrupt (source). Gemini’s headless run installs a Ctrl+C handler only when stdin is a TTY; piped, a signal is the stop (source). Cursor’s CLI has no documented stop flag: not verified.

Logged burn. In Shipped AgentRiders Phase 2, the only published flight, a dev-server kill script repeatedly matched and killed the agent’s own shell (exit 144), stalling test runs. Recovery: kill from a file and by port, not an inline process-name pattern. The log prices the burn at $0 direct; the stalls sit inside the flight’s 5 hours, and its $550 is an estimate on a subscription plan (how we count). A kill by name kills whatever matches, including the runner.

Test it. Start a run that only sleeps. Fire the stop. Check the process list and the port: children gone, the runner alive, nothing queued.

Can a hook block the tool call?

A hook runs outside the model before each tool call and can refuse it.

Block signals, last verified 2026-10-16:

MountHook and block signalWhere it fails openSource
Claude CodePreToolUse: permissionDecision: "deny", or exit 2 with the reason on stderrA timed-out hook passes unless "onFailure": "block" (v2.1.295+)hooks
CursorbeforeShellExecution: exit 2 blocksAny other non-zero exit lets the action proceedhooks
Codex CLIPreToolUse: permissionDecision: "deny", or exit 2 with the reason on stderrWhat a timed-out hook does: not verifiedhooks
Gemini CLIBeforeTool: exit 2, {"decision": "deny"}, or {"continue": false} to stop the whole loopNon-JSON stdout defaults to allowhooks reference

Two traps. A crashed hook can fail open, as the Cursor and Gemini defaults show. And a run can start with hooks off. In Claude Code, disableAllHooks turns off every hook except managed ones; --bare skips hooks, skills, plugins, MCP servers and CLAUDE.md, and whether managed hooks survive --bare is not verified (source). Codex turns hooks off with [features] hooks = false (source). Gemini’s hooks do not load at all in an untrusted folder (source).

Test it. Illustrative: a hook that denies touch probe.txt. Run a task that tries it; confirm the file is absent and the reason reached the agent. Then make the hook exit 1 and run again: that is your fail-open behaviour, written down.

Does an approval gate stop the side effect?

An approval gate halts the run at the named action and waits for a person.

Reins says the approval must name the action: destination, diff, records. What each mount gates, and what the gate becomes with nobody at the saddle, last verified 2026-10-16:

MountThe gateUnattendedSource
Claude Codeask rules: never auto-approved in any mode, including bypassPermissions; deny beats ask beats allow--permission-prompts none denies anything that would prompt; with --output-format stream-json, denials appear as permission_denied messages and in the result’s permission_denialsmodes, rule order, headless
CursorRun Mode. The Auto-review classifier is “best-effort convenience, not a security boundary”; a beforeShellExecution hook can return askagent -p writes files only with --force; what a headless prompt becomes: not verifiedrun modes, hooks, headless
Codex CLIapproval_policy = on-request (default) prompts only to escalate out of the sandboxcodex exec sets approval_policy = never unless approvals_reviewer = "auto_review" is configured; then a reviewer subagent, not a person, answers escalationsexec, config
Gemini CLIPolicy ask_user, the default for write toolsHeadless treats ask_user as denypolicy engine

Unattended, a gate becomes a denial, and a denial is still a stop. Headless Codex is the exception: nobody is asked, the sandbox holds, and the failed escalation goes straight back to the model (source).

Test it. In Claude Code, put an ask rule on Bash(git push *). Run a harmless commit task. Confirm the prompt names the push, decline, check the remote.

Is a turn cap or budget cap a stop condition?

A cap ends the run when a number is reached, finished or not.

Per-run caps, last verified 2026-10-16:

MountCapAt the limitSource
Claude Code--max-turns <n>, --max-budget-usd <amount>; print mode onlyThe turn cap exits with an error. The dollar cap checks a client-side estimate that spend can pass, so leave headroomCLI reference
CursorNone per run documented; a team USD limit in Dashboard > Spending stops the next requestAbsence inferred from forum requests: not verifiedspend limits, forum
Codex CLINo turn or spend flag; experimental [features.rollout_budget] limit_tokensThe changelog says it aborts the turn when exhausted; key names in fluxfeature_configs.rs, changelog
Gemini CLImodel.maxSessionTurns (default -1, unlimited)Headless exits 53headless

An account-level spend limit stops the next run, not this one, and an alert is not a cap (Build the harness). More at /manual/spend-cap/.

Test it. Set --max-turns 2 on a claude -p task that needs 5. Confirm the non-zero exit and read what the result says.

Does revoking the credential stop the agent?

Revoking the token stops every action that needs it, including ones you did not foresee. It is the fifth rein and the backstop.

Burns puts this in minutes zero to two: if the agent can still act, remove the access at the service. The flight above ran Cloudflare through a scoped API token (logged); rotating it would end the agent’s reach without touching the account (inference; the flight did not exercise it). Revocation does not undo what was sent or stop local writes that need no token.

Test it. Give a harmless run a throwaway token to a test resource and revoke it mid-run. The next call should fail, and the run should report that, not hunt for another credential.

How do you know the kill switch works?

A kill switch you have not fired on a harmless run is an instruction, not a control.

For each mechanism, record what stopped, what kept going, the exit code or denial reason, and who can fire it. Mark it enforced, instruction only, or not verified in your bridle (harness lesson). Then fill the kill_switch field when you log the flight; per-tool detail: the comparison page.

Questions riders ask

How do I stop a Claude Code run? Interactive: Esc interrupts the response or tool call. Headless: SIGINT ends the turn cleanly; SIGTERM exits 143 and kills the process tree. Then check for background work. Last verified 2026-10-16.

What is a stop condition for an agent loop? A rule that ends the loop whether or not the task is done: a turn count, a spend estimate, a blocked action, a person’s decision. Something outside the model must enforce it: --max-turns, a denying hook, an ask rule.

Is telling the agent to stop a kill switch? No. It is a condition with no mechanism, and the vendors say so in their own docs. Fire the real mechanism on a harmless run before you count on it.

Sources