cmux NEXT incognito: withdraw a Feed item whose workspace moved into an incognito window during the send

Merged
TE
5d ago
+64-1

Fixes #31309. Follow-up from the adjudication on #31235 (https://github.com/manaflow-ai/cmux/pull/31235#issuecomment-6563584976).

Problem. FeedHandoffDriver.adopt checked that an item's workspace or terminal is a normal window's only before it sent feed.adopt. A normal workspace that no window lists can be placed into an incognito window (reveal, openWindow(incognito: true); WindowRegistry.crossesIncognito treats an unlisted workspace as crossing nothing). If that happens while the adopt is in flight, the adopt commits and the item stays in the Feed and pushes to the iPhone, although its workspace is now an incognito window's.

Change. After the adopt returns (or an idempotency conflict confirms an earlier commit), the driver re-checks policy().frozenContent(for:). When the item is no longer a normal window's, it withdraws it with the existing pair: feed.adopt.cancel, then the daemon step. A committed adopt answers cancelled: false, so withdraw now archives the cloud copy (feed.archive, which also clears its push_due_at) before feed-local-handoff-done. An archive that fails leaves the item handing_off, and the next pass withdraws it again (same idempotency keys). The same archive applies to a frozen item from a crashed run whose adopt had committed.

Limit. A push whose delay was zero may already have gone out by the time the reply arrives; archiving cannot recall it. Nothing else of the item stays in the Feed.

Tests. Two commits: the first adds anItemWhoseWorkspaceMovesIntoAnIncognitoWindowDuringTheSendIsWithdrawn (red: only feed.adopt is sent), the second the fix. Run on the fleet with cmux-ci run ... package-test-lane.sh suite Packages/macOS/CmuxNext IncognitoFeedHandoffTests.

Spec: leo-workspace design/spaces.md "Incognito".

Agent session: agent session

šŸ¤– Generated with Claude Code


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


Summary by cubic

Fixes a race in FeedHandoffDriver where an item's workspace could move into an incognito window while its feed.adopt was in flight, leaving the item in the Feed and pushing it to the iPhone.

The driver now re-checks the window after the adopt commits and withdraws the item with feed.adopt.cancel followed by the daemon step. A committed adopt answers cancelled: false, so the cloud copy is archived first, which also clears its pending push; a failed archive leaves the item handing off and the next pass withdraws it again. Zero-delay pushes may already have gone out before the reply arrives and cannot be recalled. Adds a regression test for the race.