What the shell owns
The shell retains three assistant-related modules insrc/assistant/:
Everything else — the SSE turn loop, draft accept/reject/edit network calls, conversation list, draft state machine, activity audit, and fatigue summary — is owned by the assistant remote (
appframe-aside widget slot) and the organisation feature remote (Settings → Assistant activity).
Assistant panel and widget slot
The panel mounts as aRemoteWidgetSlot in the appframe-aside slot, outside AppFrame, so it persists across route changes. The shell loads it lazily:
- Availability entry (
assistant/availability, ≈11 KB including remote entry and share shims): loaded eagerly once per manifest to publishwindow.__STRALOS_ASSISTANT__and let the toggle render. - Widget entry (
assistant/widget, ≈135 KB): loaded once, on first open.
Toggle state storage
The shell writes and reads onlystralos.assistant.toggle. It no longer reads the legacy stralos.assistant.panel key: sessionStorage dies with the tab, and production first served users after the split shipped.
The split exists to prevent the shell from destroying a
conversationId the remote stores in the legacy key. The remote migrates the legacy key on first read.
User-menu entry
The user menu shows Talk with Doug (AI Assistant) only whileuseAssistantAvailable() returns true, so it never offers an item that opens nothing. The item calls openAssistant(), which loads the widget if needed and opens the panel; unlike the header button, it never closes it. The billing recovery menu does not show the item because the assistant panel is not mounted there.
Availability bridge
assistantBridge.ts subscribes to window.__STRALOS_ASSISTANT__ (version 1), a store the remote publishes when its availability module evaluates.
useAssistantAvailable() returns:
undefined— bridge not yet arrived; render nothing.true— assistant is available; show the toggle.false— assistant is disabled; hide the toggle.
notifyAssistantBridgeInstalled() is called by loadAssistantAvailability once the availability load resolves so that already-mounted readers re-subscribe and pick up the initial snapshot.
Assistant activity
Organisation admins can open Assistant activity in Settings. That panel is owned by the organisation feature remote, not the shell. The shell’sApp.settingsHandoff.test.tsx covers the integration path — verifying that the activity and fatigue endpoints are called with the host’s bearer token after the remote mounts through the real organisation route.
See AI copilot frontend for the ChatPanel component contract, Doug assistant frontend for the draft lifecycle, network calls, and kill switch, and Organisation settings frontend for the activity view.
