fix(desktop): heal bound views after stale runtime (salvage of #98876) - #99664
Merged
Merged
Conversation
Contributor
૮ >ﻌ< ა ci reviewran on 959c3a8 — fix(desktop): satisfy import ordering
|
This was referenced Sep 1, 2026
Closed
This was referenced Sep 1, 2026
This was referenced Sep 1, 2026
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.
Salvages #98876 by @JoaoMarcos44 (cherry-picked, authorship preserved). Refs #98683.
What this fixes
The session view's background pollers (status/approval/goal, driven by the 5s
process.listpoll inapps/desktop/src/store/composer-status.ts) receive gateway4001 "session not found"when their bound runtime id has been reaped/rotated. The existing gone-latch stops the poll storm, but nothing ever carries the gateway's "resume the stored session" verdict to the view — the window stays bound to a phantom runtime for the rest of its life, cycling the session view through loading and remounting the composer + clarify cards.This PR adds
store/runtime-gone.ts: on the 4001 verdict it latches once per runtime id and pulls the same recovery levers thesession.reclaimedpush path already uses —unbindTileRuntime(re-arms the tile's resume effect) andrequestSessionResumefor the primary chat (the only thing that bypasses itsalreadyActiveskip). Consecutive heals are capped at 3 per stored session (refunded when a binding proves healthy), so a reap-on-sight backend can't be turned into a resume loop.Cherry-picked commits (authorship preserved)
fix(desktop): latch dead runtime recovery across remounts(was 9b5ea64)fix(desktop): retain session remount polling reset(was 3dadfcc)fix(desktop): satisfy import ordering(was 7d390b8)Dropped from the original PR, and why
docs: clarify stale runtime investigation(2976e96) and thedocs/forensics/issue-98683-stale-runtime.mdfile added by the first commit — forensics notes containing Windows temp paths; investigation artifacts don't belong in the repo. The file was stripped from the cherry-pick; the code diff is otherwise identical to the original PR (net: 3 files, +287).Verification
vitest run --project ui src/store/runtime-gone.test.ts— 9/9 passedvitest run --project ui src/store/composer-status.test.ts— 19/19 passednpm run typecheck(all three tsconfigs) — cleaneslinton all four touched files — cleanscripts/audit_pr_attribution.py --fix— all contributor emails mappedLive repro: vitest/jsdom A/B against the real stores (desktop Playwright lane disabled per #76627; renderer-only change) — a throwaway harness bound a tile + active session to a dead runtime and drove
refreshBackgroundProcessesinto a gateway rejectingsession not found. Before (origin/main d10ef89):TILE_RUNTIME_AFTER_4001=runtime-dead,RESUME_REQUEST=null— view stays bound to the phantom runtime. After (this branch):TILE_RUNTIME_AFTER_4001=undefined,RESUME_REQUEST={"sequence":1,"sessionId":"stored-1"}— binding cleared and resume requested. Transient-error leg (timeout) verified to leave the binding alone.Sibling issue #98455 (generic status-stack remount reset) is intentionally out of scope, matching the original PR.
Infographic