Skip to content

Refuse stale Workspace snapshots during transfer preparation - #1301

Merged
nedtwigg merged 2 commits into
mainfrom
audit-transfer-snapshot
Oct 21, 2026
Merged

nedtwigg merged 2 commits into
mainfrom
audit-transfer-snapshot

Conversation

@nedtwigg

@nedtwigg nedtwigg commented Oct 21, 2026 •

Copy link
Copy Markdown
Member

A Workspace transfer captured its layout before awaiting CWD probes, then collected the Surfaces to move afterward. Splitting, closing, or minimizing during the probe could pair an outdated saved layout with a different live membership set.

Refuse preparation when the captured Wall or Door state changes during that wait. The existing move failure path keeps the Workspace in its source window and reports that it should be retried.

Validation: split, close, and minimize regressions failed before the fix; those cases and an unchanged Workspace with a fresh CWD pass afterward. Ordinary saves retain their existing behavior, pinned by a CWD regression that failed with the initial shared-serializer guard. All 198 Wall, transfer, and session-save tests pass, as do library types and spec/Markdown lints.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Deploying mouseterm with  Cloudflare Pages  Cloudflare Pages

Latest commit: 7b8f443
Status: ✅  Deploy successful!
Preview URL: https://104b0baf.mouseterm.pages.dev
Branch Preview URL: https://audit-transfer-snapshot.mouseterm.pages.dev

View logs

@dormouse-bot dormouse-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The refusal lives in serialize, so it applies to every ordinary save of a Workspace, not only transfer preparation. doSave calls serialize(options) whenever workspaceId is set (the standalone Window path), and flushPersistence → flush → doSave is also what WorkspaceWindow runs for the host's session-flush request, with probeCwd. Any store commit during that probe now rejects the save: a resize, setZoomed, an IframePanel navigation (updateParams + setTitle), or a tool's param update, as well as the split/close/minimize this PR targets. Before, the save still published fresh CWDs with the layout taken just before the change. Now nothing is published, and the flush loop resolves with only a debounced follow-up pending. On a quit flush, that follow-up may never run, so the aggregator keeps the previous record and its stale CWDs. The spec line added here also scopes the rule to preparation.

Scoping the check to the transfer path would avoid this: for example, make it opt-in via a transfer-only flag on the serialize options, or take the snapshot and compare it in the prepareWorkspaceTransfer wrapper in Wall.tsx, which already has lath and doorsRef. Ordinary saves would then keep their old behavior. The new test only exercises the transfer path, so it passes either way.

@nedtwigg
nedtwigg merged commit 52bbf06 into main Oct 21, 2026
15 checks passed
@nedtwigg
nedtwigg deleted the audit-transfer-snapshot branch October 21, 2026 16:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants