# Cancellation proof driver

AI-assisted; verified with the tests and tools listed above.

Both sides ran their own real server and web dev app, with fresh checkout-local databases and T3CODE_DEV_SEED=0. Browser: Chromium, 1280×800 CSS pixels, light theme. The same parent prompts below were sent through `node apps/server/src/bin.ts thread send <parent-thread-id> - --base-dir .t3 --wait --json`. The parent was started with a supported configured provider and an inexpensive model; private runtime identifiers are omitted. No database rows were inserted.

Create a synthetic empty git repository, add it with `project add`, then start a parent with `thread start <workspace> "Do not use any tools. Reply READY." --title "Background cancellation" --provider <configured-provider> --model <configured-model> --base-dir .t3 --wait --json`. Retain the returned parent thread ID.

The initial unawaited-command attempt completed before cancellation on both sides. For the actual proof, mark the command awaited as below. This is required to reach the specified running/waiting_for_children precondition.

## 1. Delegate

```text
Create a NEW task for this reproduction. Use T3 delegate_task, NOT native Agent. Title: Awaited background sleeper. mode async, isolation shared, same target provider and model as yourself. The exact child task is: "Start a long shell command with Bash command='sleep 300' and run_in_background=true. Then load and call T3's t3_background_wait with taskIds containing the background command ID Bash returned. This marks the background command awaited but does not block. After that call succeeds, end your provider turn immediately with the exact interim reply 'Background command started; waiting.' Do not use TaskOutput, Read, or any blocking wait."
Return only the new task ID. Do not cancel it or check its status yet. Do not wait for it. Your next step is to finish your own provider turn.
```

Before cancelling, send: `Call task_status once for the NEW Awaited background sleeper task. Report status and workState exactly. Do not cancel, wait, or call any other tool.` Both sides reported running/waiting_for_children, with a completed child provider turn.

## 2. Cancel (after status precondition)

```text
Cancel only the NEW Awaited background sleeper task using task_cancel. Supply a fresh clientRequestId (a new UUID you choose for this call) and reason 'Cancellation proof'. After task_cancel returns, call task_status once for that same task. Reply only with the exact cancellation response status, task_status status and workState. Do not reinterpret the results. Do not start a new task.
```

## 3. Read after stopping and restarting the same checkout server

```text
The server was restarted. Call task_status for the Awaited background sleeper task we cancelled. Report the exact status, workState, result summary, task ID. Do not cancel it again or create tasks.
```

## 4. Preserve already-published success

```text
Preservation control: delegate a NEW T3 task titled Successful control. Same provider and model. Task: 'Do not use any tools. Reply exactly CONTROL SUCCESS.' Use mode wait and wait for its successful result. Then call task_status to ensure the success is published. Only after that, call task_cancel on that completed task with a fresh UUID clientRequestId, then task_status again. Reply with the exact control status and result before and after cancellation. Do not touch the Awaited background sleeper task.
```

The uploaded observed JSON files contain allowlisted fields from real persisted tool results and parent task projections, including status reads after restart and the preservation control. Runtime provider/model metadata is omitted. The screenshots and recordings crop the conversation region to exclude private metadata; no status text was edited. The before/after screenshot pairs were identical 500 ms apart before cropping. Both recordings were visually inspected using sampled contact sheets.
