Repository navigation
fix(flow-chat): guard peer turn, cancel, queue and history state races - #3878
Merged
Merged
Conversation
- Drop a delayed DialogTurnStarted that would revive a settled turn or supersede a newer admitted turn. - Bind cancellation to the turn and device surface it was issued for, so a late failure cannot roll back a newer turn or reach another device. - Run pending queue status/remove on the surface where the send began, let peer queues drain once canonical history is ready, and keep an uncertain submission as a failed draft instead of dropping or resubmitting it. - Invalidate cached history windows when the turn catalog revision changes and reacquire the reader's range before extending it. - Report lost peer mutation acknowledgements as outcome_unknown and settle an uncertain peer session deletion by reading the metadata back.
3 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fix several state races in the flow chat that show up mostly on peer device surfaces.
DialogTurnStarted. A delayed start event could reactivate a completed/cancelled/errored turn or supersede a newer admitted turn. It is now dropped.USER_CANCELawaited imports before resolving the target, so it could send the cancel to a newly selected device, and a failed old cancel moved a newer turn back to processing. Cancellation now captures its surface and turn, checks a cancellation generation, and never rolls back on behalf of an older request.LocalSessionDriver.cancelignores a late outcome for another turn.remove/setStatusacted on the currently active surface, so a send settling after a device switch mutated the wrong queue. Peer queues were gated by local Runtime attach fences and never drained; the cancel gate was never released by an authoritative terminal record; two drains could overlap. Queue ops are now surface-scoped, peer queues drain once canonical history is ready, and an uncertain submission after a surface switch is kept as a failed draft instead of being dropped or resubmitted.loadedRanges/activeRange, so late pages from the old revision were accepted, and a live tail turn past the persisted catalog returned not-found. Cached windows are invalidated on revision change, stale retries use the current generation, and the reader reacquires its range before extending it.outcome_unknown:code, and an uncertain peer deletion is settled by an authoritative metadata read.Type and Areas
Type: bug fix
Areas: web UI (flow chat, peer device adapter)
Motivation / Impact
Users switching between devices or cancelling during peer sessions could see revived turns, wrong-device cancels, stuck or duplicated queued messages, broken history scrolling after a catalog refresh, and false "delete failed" errors.
Verification
npx vitest run src/flow_chat/store/FlowChatStore.test.ts src/flow_chat/services/flow-chat-manager src/flow_chat/state-machine/SessionStateMachine.test.ts src/flow_chat/components/modern/ModernFlowChatContainer.history-restore.test.tsx src/infrastructure/api/adapters/peer-device-adapter.test.tsinsrc/web-ui: all new tests pass. 4 existingPendingQueueModulelocalStorage persistence tests fail identically on unmodifiedmainin my environment, so they are unrelated to this change.tsc --noEmitinsrc/web-uiRemote scenarios: Peer Device Mode paths covered by unit tests with mocked transports only.
Reviewer Notes
AI-assisted change, lightly tested as listed above.
Checklist