Multi-Agent Abort With Three Coordinators, One Human, and No Shared Bus

Multi-agent abort runbook for Claude Code Projects, Cursor Projects and the OpenAI Agents API: one human interrupt path, evidence export per vendor, pause all.

Multi-agent abort hero: one switch fanning out to three vendor-shaped stops, with the evidence export drawn beneath them
One switch, three dialects, one export. The wiring is the operator's job.

Thursday, 4:10 p.m. One browser tab holds a Claude Code project with nine threads working a monorepo. A second holds a Cursor Project whose coordinator has cloud agents on the same repo’s billing service. A terminal holds an Agents API session with six subagents rewriting the fixtures the other two depend on.

Then someone in #ops posts that the schema migration all three were told to assume has been reverted. You need everything to stop, and there is no button that does that.

Multi-agent abort across vendors is the control nobody shipped in September. Each coordinator has a stop of some kind, in its own dialect, at its own scope, reachable through its own surface. None of them knows the other two exist.

What you can build instead, in a day, is a single switch you flip, a manifest that tells the switch what exists, three vendor-specific stops it fires or pages you to fire, and one evidence export per vendor that runs before anything gets deleted. That is the runbook below.

The bus is yours to build because no vendor sells one. Pretending otherwise is how you end up with cloud agents still committing forty minutes after you believed the fleet was dark.

Three coordinators in eight days, and none of them hears the others stop

Cursor shipped Projects on Sep 10, 2026, and OpenAI put the Agents API into public beta the same day; the operator’s read on each is already written (Cursor Projects against a tray fleet, Agents API continuity). Anthropic followed on Sep 17 with “Projects redesigned: from folder to conversation” (claude.com). The mechanism is the same shape as the other two: “Projects have threads that do the work and a coordinator that directs them,” each thread is “a Claude Code cloud session working on its own branch and copy of the repo,” and “Each thread can further split its delegated work into pieces using subagents, loops, and workflows when needed so large assignments finish faster.” The product read is Anthropic’s cloud coordinator; this piece is only about stopping it.

Claude Code docs page for Projects, with the public-beta notice and the right-hand contents listing Pause, archive, or delete a project Screenshot: Claude Code Docs, “Let Claude coordinate ongoing work with Projects” (undated docs page), captured Sep 19, 2026.

The docs page, “Let Claude coordinate ongoing work with Projects” (code.claude.com), is where the stop semantics live, and they reward reading with a pen. Per thread: “Stop, which replaces the send button while the thread is working, or by pressing Esc.” Per project, Pause “stops everything at once. Every running thread and the conversation are interrupted, no new threads start, routines don’t run, and the project doesn’t accept messages until you resume it.”

Archive “stops any thread that was running or watching a pull request.” Delete “permanently removes the project along with its threads, its memory, and its files,” and “Branches and pull requests the threads pushed to GitHub aren’t affected.”

Projects are “not in the terminal CLI,” and the CLI’s claude project command “is unrelated.” The docs describe no API, CLI flag or webhook for any of it. The beta is for select Pro and Max subscribers who use cloud sessions, and “There are no organization-level controls for projects during the beta.”

Everything below is about the seam between three products, each designed as if it were the only coordinator on your desk.

What stop means in each vendor’s own words, as of Sep 19

Chatbots had one stop: end the stream. Coordinators act, on machines you do not own, through workers you did not start, on branches that will outlive the tab. So the word splits into questions a chat product never had to answer: stop which unit, from where, with what effect on the workers underneath, and where does the half-done work land.

Here is what each vendor has put in writing. Every cell is verbatim-backed or says the docs are silent; nothing in it is inferred.

Question Claude Code Projects Cursor Projects / Cloud Agents OpenAI Agents API
Unit you can stop A thread (Stop or Esc); the whole project (Pause, Archive) A cloud-agent run: POST /v1/agents/{id}/runs/{runId}/cancel; nothing documented for a Project or its coordinator A session’s active turn: post {"type":"agent.session.input.cancel"} to the session’s events endpoint
From where UI only (claude.ai/code, the desktop Code tab, mobile) API v1 (public beta) or the SDK’s run.cancel(), “supported on running local and cloud runs” API only; webhooks report state and do not stop anything
Effect Pause: threads and conversation interrupted, no new threads, routines off “Cancellation is terminal”; the run goes CANCELLED and “cannot be resumed”; SDK: “in-flight tool calls stop” “The session and its previous work remain available”; watch for agent.session.turn.cancelled
Subagents under the stopped unit The docs do not say The docs do not say The docs do not say for a root cancel; the coordinator has an interrupt_subagent_call action
Delete versus compute Delete removes threads, memory, files; GitHub branches and PRs stay Agent ARCHIVED is terminal and “workspace state can be deleted” “Deleting a session neither stops its environment nor emits a deletion webhook”

Sources for the cells: the Claude projects doc above; Cursor’s Cloud Agents API endpoints, TypeScript SDK and Projects pages; OpenAI’s sessions, multi-agent and environment lifecycle guides. Cursor’s API page carries a public-beta banner and says the API may change before general availability.

OpenAI Developers docs, Run and continue sessions: the sessions-and-turns definition and the contents entry Cancel an active turn Screenshot: OpenAI Developers, “Run and continue sessions” (undated docs page), captured Sep 19, 2026.

Read the fourth row twice. Three vendors, three subagent mechanisms, and not one sentence in any of their docs says that stopping the parent stops the children. The Claude cloud-session doc says only what happens when a VM is reclaimed: “Background work that was still running when the VM was reclaimed, such as subagents and shell commands, isn’t restored” (code.claude.com). OpenAI says “A completed create or wait action does not mean the subagent finished its task,” and defaults max_concurrent_subagents to 6, “excluding the coordinator”; Cursor says nothing.

The earlier piece on interrupting coordinators defined pause, redirect and abort as contracts; this row is why the contract has to end with a sweep.

The multi-agent abort matrix as a heat table

Multi-agent abort semantics heat table: nine dimensions by three vendors, each cell shaded documented, partial, or not documented Sixteen cells are documented, four are partial, seven are silent. The silent row that matters is subagent propagation, and it is silent for all three. Source: vendor docs read Sep 19, 2026.

The chart is the table above plus four more rows (partial-work location, approval prompts, evidence after the fact, money meter), scored the only honest way: documented, partial, or the docs do not say. The API-first vendors are strong on per-unit stop and on evidence, and silent on stop-everything; the UI-first vendor is strong on stop-everything and has no programmatic surface at all. The gray band across subagent propagation is the one your abort bus has to cover with a sweep, because nobody else will.

Build the abort bus you were not sold

Budget a working day. Everything below is illustrative in shape; the endpoints and event names are the vendors’ own.

Step 1: the manifest is the bus

You cannot abort what you cannot enumerate. Before any coordinator starts, the job gets a run ID and a manifest line for every vendor unit it may touch. The coordinator’s memory of what it spawned is not authoritative; the manifest is.

# runs/2026-09-19-schema-revert.yaml — illustrative
run_id: r-0919-schema
owner: you@example.com
units:
  - vendor: anthropic-projects
    ref: "<project URL, copied from claude.ai/code/projects/browse>"   # UI only; no API
    stop: { kind: human, path: "Project settings > General > Pause" }
  - vendor: cursor-cloud-agents
    ref: { agent_id: "agt_...", run_id: "run_..." }
    stop: { kind: api, method: POST, path: "/v1/agents/{id}/runs/{runId}/cancel" }
  - vendor: openai-agents-api
    ref: { session_id: "sess_..." }
    stop: { kind: api, method: POST, path: "/v1/agents/sessions/{id}/events",
            body: { type: agent.session.input.cancel } }
repos: [org/monorepo]

Two rules. The manifest is written at spawn, not reconstructed at abort. And the Claude entry is a human step by design, because there is no other kind; write the click path into the file so the person on call is not reading docs at 4:10 p.m.

Step 2: one human interrupt path

One command, one argument, no vendor names at the call site. The human types abort r-0919-schema in one place, and the bus does the rest, including the part where it turns around and tells the human what only a human can do.

Multi-agent abort bus diagram: one switch reads the run manifest, fires a Cursor run cancel and an Agents API turn cancel, pages a human for the Claude Code Projects Pause, then exports evidence and sweeps for orphans The switch never deletes anything. It stops, exports, sweeps, and then hands the cleanup to a person.

The switch fires the vendor stops in parallel, waits on each vendor’s own confirmation signal, exports evidence, then sweeps. An abort that returns before the vendor said cancelled is a hope with a log line.

Step 3: fire each vendor’s stop and wait for its word

Cursor. One call per run in the manifest. The API says “Cancellation is terminal — the run transitions to CANCELLED and cannot be resumed.” Two error codes do useful work: “Cancelling a run that is already in a terminal state, or one that was never active, returns 409 run_not_cancellable,” which means the work was already over and your manifest was stale; and 409 agent_busy on a subsequent create means a run is still live and your cancel did not take. Treat the first as success and the second as an alarm.

The SDK path is the same stop with a nicer face: “the live stream aborts, in-flight tool calls stop,” and “Partial output (assistant text written so far) stays on the Run object.”

# illustrative; path from cursor.com/docs/cloud-agent/api/endpoints, base URL and auth per that page
curl -X POST "$CURSOR_API_BASE/v1/agents/$AGENT/runs/$RUN/cancel"
# expect the run to transition to CANCELLED; 409 run_not_cancellable means it was already over

OpenAI. One event per session. “Cancel the current turn when you want the agent to stop. The session and its previous work remain available.” Then wait for the outcome event, because “An idle session alone does not mean the turn succeeded”; the docs say to look for agent.session.turn.completed, agent.session.turn.failed, or agent.session.turn.cancelled. Do not use delete as a stop: “Deleting a session neither stops its environment nor emits a deletion webhook,” and on a self-hosted sandbox the lifecycle page tells you to delete the session and stop provider compute as separate acts.

# illustrative; shape from the Agents API sessions guide
curl -X POST "https://api.openai.com/v1/agents/sessions/$SESSION/events" \
  -H "Authorization: Bearer $OPENAI_API_KEY" -H "OpenAI-Beta: agents=v1" \
  -H "Content-Type: application/json" \
  -d '{"type":"agent.session.input.cancel"}'
# then list turns until the latest one reports cancelled, failed, or completed

Claude Code Projects. The switch cannot do this one, so it pages. The page carries the project URL, the click path (Project settings, then Pause), and the reason for Pause over Stop: Stop is per thread and you have nine of them, while Pause interrupts every thread and the conversation, blocks new threads, and turns routines off. The human acks in the manifest.

If the project should not resume at all, Archive after Pause: it “stops any thread that was running or watching a pull request,” which matters because a thread watching a PR keeps working on that PR long after you thought it was idle. Delete is a cleanup step for later, never an abort; it removes memory and files you have not exported yet.

One more Claude-specific trap. “When a thread needs your approval, the prompt is inside that thread and the thread waits until you answer it there. Telling Claude in the project conversation to go ahead doesn’t reach it.” The docs do not say whether Pause clears a pending prompt, so assume a thread parked on one is waiting rather than stopped, and that after Resume it proceeds the moment someone clicks.

The page should list threads in the Waiting on you state so the human decides each one before resuming.

Step 4: export evidence per vendor before anything is deleted

The failover-first managed agents comparison scored evidence export as a buying row; this is the operational version, run under time pressure with three different retention clocks ticking.

Vendor Pull this How Clock to beat
Cursor Per-run token usage incl. cache reads and writes; the run stream; transcripts and events.json per run GET /v1/agents/{id}/usage; Stream A Run; Cursor Cloud MCP batch-fetch-details, “up to 50 runs per batch” The stream carries X-Cursor-Stream-Retention-Seconds; after that window, 410 stream_expired
OpenAI Saved items, the turn list, per-turn status, timestamps, usage and error, per-subagent items GET /v1/agents/sessions/{id}/items?order=asc&limit=100; list turns; retrieve a turn “Streams do not replay missed events”; items are what survives
Anthropic The thread transcript in Overview, the Usage tab by thread and by model, the branches on GitHub A human reads and screenshots; no export, and “thread transcripts don’t have the share option” Delete removes the transcript; branches survive Delete

Two limits to know before an incident review asks. OpenAI’s saved items recover “completed work, but not every intermediate event you missed,” and between agents “the stream does not provide a full conversation transcript.” Cursor’s Cloud MCP is the richest surface of the three (capabilities doc); team admins can fetch transcripts across the team, the closest thing to an org-level evidence pull any of the three offers. Anthropic’s is a person with a scroll wheel.

The shape for reporting an incident that spans all three is the sibling piece on misalignment evidence export.

Step 5: sweep for what the stops did not reach

The sweep is the answer to the gray row. It checks three surfaces, none of which is the coordinator’s word.

  1. Branches. Save git ls-remote --heads origin at the abort timestamp and run it again ten minutes later; any head that moved belongs to a worker that did not stop. Cursor’s result.git on the run stream lists “the agent’s current pushed branches,” and Claude threads push to GitHub directly, so the remote is the truth.
  2. Vendor lists. List Cursor agents and their runs; list OpenAI turns and subagent items; open the Claude project Overview. A unit the vendor lists and the manifest does not is an orphan by definition.
  3. Meters. Cursor’s per-run usage endpoint, OpenAI’s per-turn usage, Anthropic’s Usage tab. Tokens accruing after the abort timestamp mean a worker is still alive; the metering side lives in subagent fan-out metering.

For OpenAI, one more habit. The harness gives the coordinator an interrupt_subagent_call, and “A message sent during an active turn steers that turn,” so the bus can steer first (interrupt your subagents, then stop) and post the cancel after. Whether a root cancel does that on its own is something the docs do not say, so do not rely on it.

Step 6: the pause-all checklist, on one page

Print it. The time budgets are illustrative and assume the manifest exists.

  1. Type abort <run-id>; confirm the manifest it loaded lists every unit you remember. Sixty seconds.
  2. Cursor cancels return CANCELLED or 409 run_not_cancellable; any other response is one retry, then an alarm. Two minutes.
  3. OpenAI cancels posted; wait for turn.cancelled on each session. Do not delete. Two minutes.
  4. Human paged for Claude: Pause, then list Waiting on you threads, then Archive if the work is dead. Three minutes, longer on a phone.
  5. Evidence pulled: Cursor usage and events.json, OpenAI items and turns, Claude Overview screenshots and the Usage tab. Ten minutes.
  6. Sweep: branches, vendor lists, meters, all filtered after the abort timestamp. Five minutes.
  7. Write the abort line into the manifest with who, when, and what the sweep found. Then, and only then, cleanup.

Step 7: drill it before Thursday

Run the switch against a throwaway job on all three vendors once, on a Tuesday, with a timer. Measure the gap between abort and the last vendor confirmation, then the gap between that confirmation and the last branch push. The second number is your orphan window, and if it is not zero the drill found the seam before an incident did.

Five ways a worker survives a multi-agent abort

A Cursor unit that was never in the manifest. The coordinator “starts a local agent” when something needs testing on your machine, and a local run is a different unit from the cloud run you recorded. Signal: a local process still writing to the worktree, or a branch the manifest never named. Detection: the sweep’s vendor list against the manifest.

An OpenAI session you deleted instead of cancelled. The API forgot it; the environment did not. Signal: provider compute still billing with no webhook to tell you, because deletion emits none. Detection: your sandbox provider’s own console, since the Agents API will not say.

A Claude thread that hits a plan limit mid-abort. A limited thread “waits and continues on its own when the limit resets, so work you left running starts using your next usage window without a message from you.” Stop on one thread does not protect the other eight; Pause is the documented control that covers them all. Signal: a branch that moves at the top of the next usage window. Detection: the branch sweep, re-run an hour later.

Evidence that expired while you were paging someone. Cursor’s stream retention window and 410 stream_expired; OpenAI’s non-replaying streams. Signal: a 410, or a gap in items around the abort. Detection: none after the fact, which is why export runs before cleanup.

A resumed project with a prompt nobody read. A Waiting on you thread proceeds when someone answers it. Signal: activity on a thread you believed was dead. Detection: the Overview states list, checked before Resume.

The operating layer owns the switch

Each of these vendors built a good coordinator and a stop that fits its own product. The seam between them is an operating-layer problem, the same one that runs a fleet from one screen: an inventory of what exists, one interrupt that fans out, evidence that lands somewhere you control, and a record for the review, which is what the manifest and the exports become a week later in fleet replay. A stop per product is not an abort bus.

None of this needs a gateway or a platform team. It needs a file, a script, a click path written down, and a drill you ran once. Then the 4:10 p.m. message in #ops is a command, not a scramble.

FAQ: multi-agent abort across vendors

Can I stop a Claude Code project from the CLI or an API?

No, as of Sep 19, 2026. The docs say Projects are not in the terminal CLI and the claude project command is unrelated. Stop and Esc work per thread and Pause per project, all in the UI. Write the click path into your run manifest so the on-call person is not searching for it.

Does cancelling a Cursor run or an Agents API turn stop its subagents?

The docs do not say, for either vendor, and Anthropic’s docs do not say it for Stop on a thread. OpenAI documents an interrupt_subagent_call the coordinator can issue. Treat propagation as unknown, sweep branches and vendor lists after every abort, and measure your orphan window in a drill.

What evidence can I export from Claude Code Projects after an abort?

None by API. The Overview pane shows each thread’s transcript and the Usage tab shows token use by thread and by model, but transcripts have no share option and there are no organization-level controls in the beta. Screenshot before you Delete, because Delete removes the transcript while the GitHub branches survive.

Sources