GPT-6 Astra can continue while your application runs an asynchronous tool, which means your application owns the awkward boundary between a user’s cancellation and the external job’s actual lifecycle. Treat those as two different facts.
Keep two cancellation states
Record task_cancelled when the user stops the Astra task. Separately track the external job as running, cancel_requested, stopped, completed, or unknown. A cancellation request is not proof that the job stopped. Only the job system’s own contract can establish that transition. If it offers cancellation, call it and persist the response; if it does not, keep the external state unknown rather than inventing success.
Make late results harmless by default
When a result arrives after task_cancelled, do not silently reopen the task or apply the result to a new attempt. Match it to the original job record, preserve the result for audit or an explicit recovery flow, and discard it from the cancelled task’s user-visible state. If your product intentionally supports recovery, require a new, explicit task to adopt the result and show that it came from late work. Keep the original job identity; an identifier alone does not make cancellation or retry safe.
A small state table makes the policy testable:
| Task state | External job state | Late result | Application action |
|---|---|---|---|
| active | running | no | Accept only through the original correlation record. |
| cancelled | cancel requested/unknown | yes | Keep inert; reconcile job state; do not reopen. |
| cancelled | stopped | yes | Retain as a record; no task mutation. |
| cancelled | completed | yes | Retain and require explicit recovery before use. |
This design follows the guidance that the application executes asynchronous tools and manages pending work. It does not claim that Astra, or an external tool provider, supplies job termination or rollback. For every integration, document who can stop the job, what confirmation means, and how an unknown result is reconciled before allowing retries.