fix(desktop): gate branch publish on workspace identity like cwd - #93216
ClintonEmok wants to merge 3 commits into
Conversation
A background Kanban worker's session.info carries the worker's PR-worktree cwd AND branch. handleSessionInfoEvent guarded the foreground cwd write with sessionInfoDescribesSelectedSession(), but the branch write beside it was unguarded — a worker's runtime update rewrote the default chat's composer branch/coding rail while the conversation never moved (NousResearch#92888). Extract the identity predicate into session-info-gate.ts (one resolver, shared answer) and gate BOTH writes on it: a worker event with a different stored_session_id can no longer touch the foreground composer's cwd or branch, while absent ids (lazy sessions), direct matches, and compression-lineage matches keep their existing behavior. Covered by unit tests: direct match, absent id, foreign worker id, fresh-draft rejection, lineage rotation match.
Replace the inline import() type annotation on importOriginal with a top-level 'import type * as sessionStore' reference.
Solid fix with the right shape: the unguarded branch publish was a genuine cross-session leak (a Kanban tile's PR-worktree branch rewrote the default chat's coding rail), and gating it on the same predicate as cwd closes the whole bug class rather than special-casing one field. Extracting
Minor: the test file's hand-rolled |
… log absent-id publishes, note cold-start window - The workspace-identity rationale now lives once in session-info-gate.ts; the call site points at it instead of restating. - Absent-id publishes stay allowed (NousResearch#71254) but emit a debug line, so a recurrence of this leak via a lazy path is diagnosable from one log. - Document the cold-start window where the lineage fallback drops a rotated-tip branch update until the first sessions refresh: accepted, self-healing on the next session.info heartbeat; a queue would need invalidation on every list mutation to stay honest. Refs NousResearch#93216
|
All three addressed in 2046cf8:
|
|
Closing per request. |
What does this PR do?
A background Kanban worker running in a PR worktree could rewrite the FOREGROUND composer's workspace state while the default chat never moved (#92888): the composer's coding rail / branch flipped to the worker's checkout mid-conversation.
In handleSessionInfoEvent, the foreground cwd write was already guarded by sessionInfoDescribesSelectedSession() — an event may only claim cwd when its durable stored_session_id matches (or lineage-matches) the selected conversation. But setCurrentBranch() right beside it had NO such guard. session.info heartbeats from a worker profile therefore carried the worker's branch straight into the selected chat's composer.
The fix
Per-session cache updates via updateSessionState are untouched — background/tile state continues to update independently, exactly as the issue's invariant requires.
Related Issue
Fixes #92888
(#92811 is the roster-spinner fix and is unrelated; #90006 adjacency noted by the reporter.)
Type of Change
Changes Made
How to Test
Checklist
Code
Documentation and Housekeeping