You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Reconcile a dispatched control operation instead of reporting it as failed #3234
That is the correct contract — the Host may already have committed and durably flushed the mutation before the response was lost. What is missing is anything a caller can do about it. There is no operation identity on the wire and no reconciliation helper, so every control caller passes the interruption straight through to the user as a failure, and a retry can only produce a conflict.
Desktop has one facility here, isReconnectableReadFailure in apps/desktop/src/main/ipc-reconnect-policy.ts, and it applies to queries only.
Where it shows
Raised in review of #3199 for goal.arm, which is the sharpest case because a committed Goal spends tokens: the dialog says the Goal could not be set, while the Session may in fact be armed, and the user's next ordinary Turn then runs under it. The Goal indicator (useSessionGoal) does show the real state with a one-click clear, so the outcome is visible and reversible, but the message the user was given is wrong.
The same shape applies to the other control operations — goal.control, session continuity, hosted execution, message and turn mutations.
Suggested direction
Two levels, either of which is worth having on its own:
Reconcile after a dispatched interruption.goal.query is a retryable query, so a caller can reconnect, read the canonical state, and compare it against the known pre-state and the request it sent. That needs no protocol change and would let the dialog say "connection lost; the current Goal is X" instead of "the goal could not be set".
Durable operation identity. A per-operation id the Host records with the commit would give the stronger contract — an unambiguous answer to "did my mutation land", rather than an inference from state. This is a public contract change and needs its own architecture decision.
Building either of these for goal.arm alone would add a public contract inside a feature PR rather than extend an existing seam, so #3199 keeps the shared contract and this is tracked separately.
I’d like to take this issue. I’ll start with reconciliation after dispatched interruptions, add coverage for commit-success followed by response loss, and keep durable operation identity as a separate protocol/architecture decision.
Activity
Sun-GLiang commentedon Aug 19, 2026
I’d like to take this issue. I’ll start with reconciliation after dispatched interruptions, add coverage for commit-success followed by response loss, and keep durable operation identity as a separate protocol/architecture decision.
Astro-Han commentedon Aug 19, 2026
Assigned!
fix(desktop): reconcile goal arm across reconnects (apache#3363)