# What Happens When a Background Task Is Cancelled in Codex: Turn Interrupt or Process Termination?

> Explore what happens when a background task is cancelled in Codex. Understand if it's a turn interrupt or process termination and how the system handles it.

- Repository: [OpenAI/codex-plugin-cc](https://github.com/openai/codex-plugin-cc)
- Tags: internals
- Published: 2026-07-28

---

**When you cancel a background task in the Codex runtime, the system first attempts a turn interrupt against the remote Claude session, then falls back to terminating the underlying OS process tree if necessary.**

Cancelling a background task in the `openai/codex-plugin-cc` repository is not a simple process kill. Instead, the runtime implements a coordinated two-phase shutdown that prioritizes graceful interruption of the AI turn before forcing process termination.

## The Two-Phase Cancellation Sequence

The Codex runtime handles cancellation through a specific orchestration between the app-server and the local process manager. This ensures that brokered tasks receive proper cleanup signals before hard termination.

### Phase 1: Turn Interrupt Attempt

When you issue a cancel command, the runtime first sends a **turn interrupt** request to the shared app-server coordinating the remote Claude turn. This is recorded in the cancellation payload with `turnInterruptAttempted: true` in the JSON response. If the interrupt succeeds, the payload includes `turnInterrupted: true`, allowing the Claude session to exit gracefully and release resources.

This phase applies specifically to tasks that are actively engaged in a Claude turn. The interrupt signals the AI to stop processing without immediately killing the underlying worker.

### Phase 2: Process Termination Fallback

If the turn interrupt fails or the job does not belong to an active Claude turn, the runtime proceeds to **process termination**. The `terminateProcessTree` function in `plugins/codex/scripts/lib/process.mjs` handles the actual OS-level cleanup.

On Unix systems, this kills the entire process group. On Windows, it uses `taskkill` to terminate the process tree. This ensures no zombie processes remain regardless of platform.

## How to Cancel a Background Task

Use the `codex-companion.mjs` CLI to cancel specific jobs by ID. The `--json` flag returns detailed status about the interruption attempt.

```bash

# Cancel a specific background job (e.g., "task-live")

node scripts/codex-companion.mjs cancel task-live --json

```

The command returns a JSON object indicating whether the turn interrupt succeeded:

```json
{
  "status": "cancelled",
  "turnInterruptAttempted": true,
  "turnInterrupted": true,
  "jobId": "task-live"
}

```

If `turnInterrupted` is `false`, the runtime has proceeded directly to process termination or the interrupt timed out.

## Key Implementation Files

The cancellation logic spans three critical files in the repository:

- **`plugins/codex/scripts/lib/process.mjs`** – Implements `terminateProcessTree`, which kills the process group on Unix or invokes `taskkill` on Windows.
- **`plugins/codex/scripts/codex-companion.mjs`** – Handles the `cancel` command, constructs the cancellation payload, and triggers the turn interrupt request.
- **`tests/runtime.test.mjs`** – Contains unit tests verifying that cancellation sends the turn interrupt signal and correctly marks jobs as cancelled.

## Summary

- **Background task cancellation** is a two-step procedure, not a single kill signal.
- The runtime first attempts a **turn interrupt** via the shared app-server to gracefully stop the Claude session.
- If the interrupt fails or is inapplicable, **`terminateProcessTree`** forcefully kills the OS process group.
- The JSON response distinguishes between `turnInterruptAttempted` and `turnInterrupted` to indicate success at the AI layer versus the process layer.

## Frequently Asked Questions

### Does cancelling a background task immediately kill the process?

No. According to the source code in `openai/codex-plugin-cc`, cancellation first attempts a turn interrupt to gracefully stop the Claude session. Process termination via `terminateProcessTree` only occurs if the interrupt fails or the task is not associated with an active turn.

### What is the difference between turn interrupt and process termination?

A **turn interrupt** signals the remote Claude app-server to stop the current AI turn gracefully, setting `turnInterrupted: true` in the response. **Process termination** invokes `terminateProcessTree` in `plugins/codex/scripts/lib/process.mjs` to kill the underlying OS process tree using Unix process groups or Windows `taskkill`.

### How can I verify if a turn interrupt succeeded?

Check the JSON output from the cancel command. If `turnInterrupted: true` appears in the response, the Claude session was successfully interrupted. If only `turnInterruptAttempted: true` is present, the system proceeded to process termination instead.

### Is the cancellation behavior different on Windows versus Unix systems?

The high-level two-phase sequence remains identical, but the **process termination** implementation differs. On Unix, `terminateProcessTree` kills the process group, while on Windows it uses `taskkill`. Both ensure complete cleanup of the background task's process tree.