cmux NEXT: incognito windows leave nothing in banners, quit files or space bars

Merged
TE
6d ago
+536-19

Problem

An incognito window left traces outside itself (spaces-incognito-audit leaks 5, 6 and 9). Leo asked for incognito spaces on 2026-10-31. The spec (leo-workspace design/spaces.md, "Incognito") says: "Normal and incognito content never mix", and nothing of the window is kept.

  • Leak 5: macOS banners carried the workspace name, tab, agent state and message into Notification Center history.
  • Leak 6: At quit, the app wrote incognito agent chats' composers (chips and shell command) and page screenshots for the next launch.
  • Leak 9: Every normal window's space bar listed the Incognito space, so the normal windows' sidebar snapshots recorded it.

Change

  • Banners: DesktopNotifier.post(incognito:) replaces an incognito workspace's banner with a generic one. The title is "Incognito" and the body is "A tab in an incognito window needs you." It carries no subtitle, status badge or Allow/Deny. posted records what is shown. A click still opens the tab.
  • Quit: the new AgentQuitFiles filters incognito tabs out of the composers and page images that QuitCoordinator saves.
  • Space bar: the new IncognitoSpaceMarks records each incognito space. New Incognito Space marks it before the daemon mirrors it, so no frame lists it. SidebarSpaceBar.profiles(_:window:windows:) hides every marked space except the window's own incognito space.
  • Localization: both new strings are added to NotificationsPanel.xcstrings in all 21 of its locales, which include the 9 app locales.

God types are net zero: WindowManager gains one stored property and merges one doc comment, and the other god files change only lines in place.

Tests

  • Commit 1 adds failing tests only (IncognitoSurfacesTests).
  • Commit 2 adds the fix.
  • The fleet package suite runs red at the test commit and green at the head, together with the nearby notification, relaunch-wake and space suites.

Not covered (residual)

  • An open incognito chat's unsent draft is still kept in agent-unsent-drafts.json while the window is open.
  • Feed and iPhone push items are not filtered here.
  • Mobile (leak 3) is a separate PR.

🤖 Generated with Claude Code

Agent session: agent session


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Stops incognito windows from leaving traces outside themselves—in Notification Center history, in the files the quit writes for the next launch, and in normal windows' space bars.

  • Banners from an incognito window—agent, passkey, or sandboxed Run—now show a generic "Incognito" title and body with no subtitle, status badge, attachment, or Allow/Deny; clicking still opens the tab. A passkey request whose tab closed while waiting also shows the generic banner.
  • Runs and hand-offs from incognito chats are never saved for the next launch or opened outside their window; a Run whose tab is already gone counts as incognito.
  • The quit no longer saves incognito chats' composers or page images. It collects the incognito tabs before the window step closes the incognito workspaces, since a removed tab would no longer read as incognito.
  • Normal windows' space bars no longer list an incognito space (so their sidebar snapshots don't record it); an incognito window still shows its own space.
  • Both new banner strings are translated in all 21 NotificationsPanel locales.