hermes-agent/apps/desktop/src/app/session/hooks
Brooklyn Nicholson f7bf740640 fix(desktop): reject cross-wired runtime-id cache on session resume
resumeSession's warm-cache fast-path trusted the
storedSessionId -> runtimeId -> ClientSessionState mapping without
checking the cached state still BELONGS to the session being resumed.
A pooled profile backend that gets idle-reaped and respawned
(pruneSecondaryGateways) re-mints runtime ids, so a recycled id can
resolve to a live-but-DIFFERENT session's cache entry. The only
existing guard was a session.usage 404 -- that catches a fully-dead
runtime id, but a recycled id still 200s, so the fast-path happily
painted the wrong transcript under the current route (open chat A,
chat B loads).

Fold the belongs-to check into a single takeWarmCache() helper used at
BOTH cache reads -- the early transcript-keep decision and the fast-path
itself -- so a cross-wired entry can't even briefly flash a stale
transcript before the full resume repaints. On a mismatch the helper
purges both stale map entries and reports a miss, falling through to a
full resume that rebinds a correct runtime id. The full-resume path
already guards its final paint with isCurrentResume(), so only the
cached fast-path was missing the belongs-to check.

Pre-existing bug from the initial desktop app (#20059); not introduced
by the session-switch perf work (#49807), which left these lines
untouched.

Tests: two cases in use-session-actions.test.tsx driven through a
harness that owns the two cache maps -- a cross-wired mapping is
rejected + purged (the bug), and a correctly-wired cache still serves
from memory with no needless refetch (no perf regression).

Supersedes #50464 by @professorpalmer, reimplemented to also guard the
early transcript-keep read (whole-class fix, not just the fast-path).

Co-authored-by: professorpalmer <professorpalmer@users.noreply.github.com>
2026-06-25 16:11:18 -05:00
..
use-context-suggestions.ts Add Hermes desktop app (#20059) 2026-05-31 17:46:56 -05:00
use-cwd-actions.ts Refactor desktop i18n field copy into nested structures 2026-06-06 07:51:44 -07:00
use-hermes-config.ts Add Hermes desktop app (#20059) 2026-05-31 17:46:56 -05:00
use-message-stream.ts feat(desktop): floating pet, pop-out overlay + Cmd+K picker 2026-06-20 14:18:40 -05:00
use-model-controls.test.tsx refactor(desktop): make composer model picker sticky session state 2026-06-16 09:50:07 -05:00
use-model-controls.ts refactor(desktop): make composer model picker sticky session state 2026-06-16 09:50:07 -05:00
use-preview-routing.test.tsx fix(desktop): stop auto-opening tool previews 2026-06-22 19:21:20 -05:00
use-preview-routing.ts fix(desktop): stop auto-opening tool previews 2026-06-22 19:21:20 -05:00
use-prompt-actions.test.tsx fix(desktop): handle slash exec dispatch payloads (#49358) 2026-06-19 21:11:16 -05:00
use-prompt-actions.ts fix(desktop): stop refText crash on undefined composer attachment holes 2026-06-24 18:22:01 -07:00
use-route-resume.test.tsx fix(desktop): recover stranded session windows when resume fails (#47655) 2026-06-17 17:33:53 -04:00
use-route-resume.ts fix(desktop): recover stranded session windows when resume fails (#47655) 2026-06-17 17:33:53 -04:00
use-session-actions.test.tsx fix(desktop): reject cross-wired runtime-id cache on session resume 2026-06-25 16:11:18 -05:00
use-session-actions.ts fix(desktop): reject cross-wired runtime-id cache on session resume 2026-06-25 16:11:18 -05:00
use-session-state-cache.test.tsx fix(desktop): stop a failed turn leaking into every other thread 2026-06-17 05:07:48 -07:00
use-session-state-cache.ts fix(desktop): let the session watchdog heal a stuck "looping" turn 2026-06-24 18:36:17 -05:00