fix(desktop): prevent prompt.submit targeting stale runtime session when identity is already split - #64814
fix(desktop): prevent prompt.submit targeting stale runtime session when identity is already split#64814Apaarmeet wants to merge 0 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes a Desktop submit-path race where prompt.submit could target a stale runtime session even though the UI’s stored session selection and route token already pointed at a different conversation at submit entry time (the pre-existing split state wasn’t caught by the existing “drift during async pipeline” guard). It adds an entry-time ownership check so the submit path falls back to the resume flow when the runtime session does not belong to the selected stored session, and includes a regression test for the A/B/B split scenario.
Changes:
- Adds
getStoredSessionIdForRuntimeIdplumbing and an entry-time consistency check inuseSubmitPrompt()to invalidate mismatched runtime session IDs. - Threads
getStoredSessionIdForRuntimeIdthroughusePromptActions()and wires it up from DesktopController using the runtime↔stored session cache. - Adds a Vitest regression test covering the “runtime A / stored B / route B at entry” misrouting scenario (#64789).
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| apps/desktop/src/app/session/hooks/use-prompt-actions/submit.ts | Adds an entry-time runtime→stored ownership check to avoid submitting to a stale runtime session when identities are already split. |
| apps/desktop/src/app/session/hooks/use-prompt-actions/index.ts | Threads the new dependency through usePromptActions into the submit hook. |
| apps/desktop/src/app/desktop-controller.tsx | Provides the runtime→stored lookup function from the session cache mapping. |
| apps/desktop/src/app/session/hooks/use-prompt-actions/index.test.tsx | Adds a regression test for the pre-existing A/B/B split at submit entry (#64789). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Thanks for picking this up. The root-cause diagnosis is correct: the existing drift guard does not catch an A/B/B split that already exists at submit entry. I checked the current PR merge ref and reproduced one remaining unsafe path. 1. Reverse-map misses still fail open
This means the current condition can accept an unverified runtime: A temporary regression test reproduced this exact result: The committed regression test only covers the cache-hit case because it pre-populates: 2. Resume failure can silently retarget to a new sessionWhen the ownership check does reject A, Suggested minimum repair
The current patch fixes the known cache-hit instance, but does not yet close the full #64789 bug class. |
|
Thankyou for reviewing my changes, I have addressed all the remaining issues in my current patch and edit the tests for that and all 50 test passed |
What does this PR do?
Fixes a race condition in the Desktop app where
prompt.submitcould send a message to a stale runtime session when the three session identities (runtime session, selected stored session, route token) were already split at submit entry. The existing #54527 drift guard only detects stored/route changes during the async pipeline, not a split that already exists at entry (e.g. runtime=A, stored=B, route=B). Adds an entry-time consistency check that verifies the runtime session belongs to the selected stored session before accepting it as the submit target, redirecting to the resume path when they don't match.Related Issue
Fixes #64789
Type of Change
Changes Made
apps/desktop/src/app/session/hooks/use-prompt-actions/submit.ts— AddedgetStoredSessionIdForRuntimeIdtoSubmitPromptDepsinterface, destructured from deps, added touseCallbackdep array. Added entry-time consistency check after line 231 that nulls out the runtime session ID when it doesn't belong to the selected stored session, causing the existing resume path to pick up the correct session.apps/desktop/src/app/session/hooks/use-prompt-actions/index.ts— AddedgetStoredSessionIdForRuntimeIdtoPromptActionsOptionsinterface, threaded through touseSubmitPrompt.apps/desktop/src/app/desktop-controller.tsx— WiredgetStoredSessionIdForRuntimeIdusingstoredSessionIdForNotificationwrapper over the existingruntimeIdByStoredSessionIdRef.apps/desktop/src/app/session/hooks/use-prompt-actions/index.test.tsx— AddedgetStoredSessionIdForRuntimeIdto Harness component (optional prop with default). Added regression test covering the A/B/B split scenario (runtime A / stored B / route B at entry, no changes during pipeline).How to Test
activeSessionIdremains Aprompt.submit({ session_id: "rt-session-a" })— message lands in A, permanently lost from BsessionId, the resume path resumes stored B, andprompt.submittargets the correct runtime session for BUnit test:
npx vitest run src/app/session/hooks/use-prompt-actions/index.test.tsx— 46 tests pass including the new #64789 regression test.Checklist
fix(desktop): prevent prompt.submit targeting stale runtime when identity is already split)Documentation & Housekeeping