🐛 fix(hetero): stop AskUserQuestion cards from freezing after the producer times out (#19804)
* 🐛 fix(hetero): stop AskUserQuestion cards from freezing after the producer times out The card's countdown started at mount while the producer's ask-user bridge stops waiting at its own deadline (and its long-poll stops with it). Both clocks are 10 minutes, but the producer's always starts first, so the card auto-submitted option 1 into a producer that had just stopped listening. No ACK could come back, and the card parked on `pending + resolving` with Submit spinning and every button disabled — permanently. - Countdown reads the producer's persisted deadline (`pluginState.heterogeneousIntervention.deadline`) instead of restarting on every remount. - The timeout fallback answers inside the last 5 seconds, while the bridge is still listening, and never after a known producer deadline. - A question past the producer's deadline is no longer offered as a card on any surface; its tool row states that it timed out. - A submit the producer never acknowledges settles as answered after 30s and leaves the surface instead of being re-offered. The settle writes the `pluginIntervention` projection the card list reads, rather than waiting on the server echo. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * 🐛 fix(hetero): expire intervention cards live and settle skips as skipped Addresses Codex review on #19804. - Pending cards past the producer's deadline were only dropped when a store update happened to re-run the selector. Provider-owned-option cards never auto-answer, so nothing wrote at expiry and an unanswerable card stayed on screen. Entries now carry the producer deadline, and `useDeadlineClock` re-renders consumers when the next one passes: the InterventionBar, the global approval island, and the assistant-turn-settled watcher. - The inline tool row had the same gap: its "timed out" label only re-evaluated on render, so the row sat blank after the card left. `useIsTimedOutUnanswered` flips it at the deadline; an answer already in flight is never labelled as timed out. - The no-ACK settle wrote `approved` for every action. A skip now settles as rejected + skipped and a cancel as rejected, matching the local desktop path. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
A
Arvin Xu committed
878e802cebfc9da80ce7654a0405424a73748934
Parent: 11f36dd
Committed by GitHub <noreply@github.com>
on 9/22/2026, 6:36:49 PM