---
title: Isolated Session View (experimental)
---

# Isolated Session View (experimental)

## What it is

**What it is:** an opt-in performance mode that renders the **active session's
chat in its own background renderer process**, embedded invisibly inside the
main window. The app looks and behaves exactly the same — same sidebar, same
panel area, same composer — but the conversation you're looking at no longer
shares a rendering thread with the rest of the app, so switching into it and
typing in it stay fast even while Omniscio is grinding through dozens of other
sessions' updates. There is always exactly **one** window and at most **one**
extra process — sessions are swapped _into_ the single embedded view in place,
never one process per session.

**Where:** Settings → Performance → **"Isolated session view (experimental)"**.
Default **OFF**. Takes effect on the next session you click. Desktop only
(mobile layout always uses the normal inline panel).

### Why it exists (measured)

On a heavily loaded shell thread (load injector calibrated to real traces),
the end-to-end _click → session content painted_ time, 40 switches per arm:

|                               | typical (p50) | slow-case (p90) | worst    |
| ----------------------------- | ------------- | --------------- | -------- |
| Normal panel, under load      | 222ms         | 413ms           | 825ms    |
| **Isolated view, under load** | **34ms**      | **75ms**        | **99ms** |

Typing latency inside the isolated view stays ~2–3ms per keystroke regardless
of shell load. The measurement harness is
`tests/perf/session-switch-isolation-ab.spec.ts` (GO/NO-GO bar in
`tests/perf/isolation-ab-logic.ts`); the mechanism E2E is
`tests/e2e/ui/isolated-session-view-spike.spec.ts`.

## Where to find it

**Settings → Performance → "Isolated session view (experimental)"**. It is **off** by default and takes effect on the next session you click. Desktop only — the mobile layout always uses the normal inline panel.

## How it behaves

### How it works

- When the toggle is ON and you click a session in the sidebar, the Dashboard
  **stages** that session (`stagedSessionId` in the session-presence slice)
  instead of revealing an inline panel. A host component
  (`IsolatedSessionViewHost.tsx`) mounts a single Electron `<webview>` whose
  document is the app's own renderer entry in embedded-guest mode
  (`?detached=<sessionId>&embedded=1` → `DetachedSessionApp` — the same
  full-parity session shell the Pop Out feature uses: composer, approvals,
  question widgets, everything).
- Clicking another session does **not** reload that document: the main process
  re-points the guest (`ISOLATED_VIEW_STAGE` → `ISOLATED_VIEW_STAGE_LOAD`
  push) and the guest rebinds in place, guarded by a monotonically increasing
  swap token so rapid back-and-forth clicks can never resurrect a stale
  session.
- **The guest keeps its own warm pool (2026-06-20).** It used to tear the panel
  down on every switch (a brief "Loading…" → re-fetch → re-render → scroll), so
  switching back to a session you'd just left still "went through a render". Now
  the guest keeps recently-viewed sessions mounted (hidden) so switching **back**
  is an instant reveal, and it pre-builds your most-recent **inbox** sessions in
  the background (the shell relays that set) so even a **first** click into one
  is instant. Because those panels are no longer mounted heavily in the main
  process while the view covers the screen, the memory mostly **moves** to the
  guest rather than adding.
- The guest receives exactly the pushes a popped-out window would (session
  events for its pinned session + the small global allowlist), delivered
  through the same push filter (`detached-push-filter.ts`), via a
  window-registry entry with role `embedded-session-view`.
- Security: the app's standard preload is allowed inside a `<webview>` ONLY
  when the src is the app's own renderer entry (exact pairing rule in
  `webview-security.ts`); the guest keeps the forced posture (`sandbox: true`,
  `contextIsolation: true`, `nodeIntegration: false`), and the attach handler
  registers only a live `<webview>` guest of the main window.
- Because the embedded view is a normal DOM element, menus, dialogs, and
  tooltips naturally stack above it — no special z-order machinery.

### Failure behavior (never a dead panel)

Any failure — preload bridge missing, attach rejected, staging refused, guest
renderer crash — silently clears the staged session, and the normal inline
panel mounts on the next render. No error toast: falling back to today's
behavior _is_ the recovery.

### Kill switches

- The Settings toggle itself (`isolatedSessionViewEnabled`, default `false`).
- `AMC_DISABLE_ISOLATED_SESSION_VIEW=1` env var — force-OFF regardless of the
  setting (it can never force the mode ON).

### v1 limits

- The guest keeps a small warm pool (active + recently-viewed + your recent
  inbox set), but only the **active** session receives live updates; a hidden
  warm panel refreshes the instant you switch into it. (Making every warm panel
  live would mean routing pushes to a set, which is security-sensitive — deferred.)
- Desktop only; mobile is untouched.
- A popped-out (detached) session is never staged — Pop Out wins.
- App keyboard shortcuts work while typing/clicking inside the view (fixed
  2026-06-11 after a user report): every trusted keydown in the embedded view
  is forwarded to the main window and runs through the normal shortcut
  pipeline, so session navigation, Ctrl+T, Ctrl+K, Ctrl+= / Ctrl+- text size
  and the rest behave exactly as in the inline panel. The one deliberate
  exception: Ctrl+Z while typing in the view's composer stays the textarea's
  native text-undo.
- The view follows ALL appearance settings live (fontSize fixed 2026-06-11
  after a user report; theme, accent/visual theme, chat depth, and Motion &
  Polish generalized the same day): changes apply to the embedded view (and
  pop-outs) the moment they land, no restage needed.
- Right-click works inside the view (fixed 2026-06-11): selected text and the
  composer get the same styled Copy/Cut/Paste menu as the main window,
  rendered in the view's own document, with actions applied to the view.
- The brief boot-window race (switching again during the view's very first
  ~1–2s boot could strand the previous session until the next click) was
  FIXED 2026-06-11 — the view now reconciles its staged target right after
  it finishes booting.
- Costs one extra renderer process while staged (measured: ~195MB working
  set — about the same as one Pop Out window).

## Related

- Contract (invariants + locking tests):
  `.claude/memory/contracts/isolated-session-view-contract.md`
- Pop Out (the same guest shell in its own OS window):
  [detached-session-window.md](detached-session-window.md)
- The inline panel's own switch optimizations:
  [inbox-prerender.md](inbox-prerender.md), [instant-new-session.md](instant-new-session.md)
