Audit follow-up to the Planning/subtask project-switch fixes — three more
surfaces had the same bug class:
- Embedded ChatView survived a project swap when both projects last used
the chat view: useChat refetched the session list on projectId change
but never reset activeSession/messages or closed the live stream, so
project A's conversation kept rendering (and streaming) under project B.
Now keyed by project like Quick Chat's FN-8257 FloatingWindow key.
- MissionManager's nested always-mounted MissionInterviewModal (and the
interviewTarget-driven MilestoneSliceInterviewModal) reconnected the
previous project's interview session under the new projectId and saved
the goal draft under the new project's kb-mission-last-goal key.
MissionManager is now keyed by project; the interview modal saves an
un-started goal draft on unmount under its own project id.
- Always-mounted GitHubImportModal's persist effect depends on projectId,
so a swap re-fired it with the old project's provider/labels/repo
selections and wrote them under the new project's storage key. Now
keyed by project (the embedded Import Tasks view already unmounted).
Verified SAFE without changes: TaskDetail/Group/Files/WorkflowNodeEditor
(conditionally rendered + closed on swap), Settings/Usage/Schedules/
Agents (cross-project by design or self-correcting projectId-keyed
hydration), and the remaining embedded views (projectId-keyed fetch
hooks, no streams or scoped drafts).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>