+After the interrupt commit, the worker best-effort reconciles the `cancel_requested` rows: it dials the recorded agent with a short timeout and sends a kill signal. A confirmed outcome (the agent definitively has no such process, reports it already exited, or a post-kill snapshot shows exit) resolves the row to `canceled`. A delivered but unconfirmed kill records `cancel_signal_sent_at` and leaves the row `cancel_requested` with its full process identity, so a later reconciler can still act on it. Rows without a recorded process identity are resolved by probing the token index of the dispatch target recorded at claim time, never the chat's current agent: a found process is first adopted onto the row (so a transient kill failure leaves durable process identity for the sweep, not a token-only row) and then goes through the normal kill-and-confirm flow, a pending reservation or an absent token is re-probed until the record grace window since the claim closes (an interrupted in-flight `StartProcess` may not have reached the agent yet, so no reservation exists and a process can still appear moments after the commit), a trustworthy absent token resolves to `canceled` only after that window, and transport failures that persist leave the row for a later reconciler. When the token index cannot help (untrustworthy absence, agents without the probe route, no recorded dispatch target), the reconciler waits out the same grace window for a late handle write, since `RecordStart` runs on an uncanceled bound and may land after the commit; a handle that arrives gets the kill flow, and only then does the row resolve to `unknown`. The `unknown` write itself requires the row to still have no process identity: a handle landing concurrently wins the race, and the reconciler then runs the kill flow on the freshly identified process instead. The interrupt commit maps background rows to `detached` only when their handle is recorded, and the synthetic result committed for such a call carries the process handle: the process is deliberately left alive, and a generic cancellation would strand it without an addressable ID. A background row whose start was still in flight becomes `cancel_requested`: its committed synthetic result carries no handle, so a process identified late (by the record write or the token probe) is killed like foreground work instead of being left running unaddressable. This runs after the commit, so a slow or unreachable agent never delays the interrupt.
0 commit comments