4.1 KiB
Rolling a packaged Windows build back to an older release
The on-disk suite drives both builds' real Store over a real orca-data.json.
That leaves three things it cannot reach: electron-builder packaging, the boot
sequence that decides where userData lives and which cohort migrations run, and
a real userData directory. This page records what those add, measured rather
than assumed.
The measurement
On Windows 11 10.0.26200 (x64), two packages built from source on the same
host with pnpm run build:unpack, each from its own node_modules:
- new — the composed stack at
84e703ce97a, 241 commits ahead of the tag - old — the
v1.4.199tag
Both ran headless against an isolated --user-data-dir; nothing touched the
real profile. State was written by the new build through its own packaged CLI —
a repo, a worktree, a terminal tab — and an ssh:* host partition was injected
so the rollback could be asked about rows an old build did not write.
Every leg ran with a same-version control on a byte-identical copy of the same state, because a restart mutates the session blob on its own and the downgrade would otherwise be credited with that churn.
| question | result |
|---|---|
| old build reads new state | yes — no throw, no salvage, no dropped row |
| old build writes back a shape new still accepts | yes — return leg diffs 0 keys removed, 0 added |
| old build deletes what it does not understand | no — its diff matches the control except the running build's version |
workspaceSessionsByHostId["ssh:*"] tab rows survived all three legs, as did
repos, projects, projectHostSetups, worktreeMeta,
worktreeIdentityAliases and worktreeMetaByIdentity.
Read the control, not the downgrade diff
A restart of either build on this state empties
workspaceSession.unifiedTabs and tabGroups for the worktree and drops
tabGroupLayouts, activeGroupIdByWorktree and the pane title under
terminalLayoutsByTabId. It also writes _sortBySmartMigrated and flips
ui.sortBy from recent to smart.
None of that is rollback behaviour — the same-version control produces the same removals on the same input. Reading the downgrade diff alone reports terminal tab-group loss that is not there.
An injected partition has to satisfy the session schema or both builds discard
it identically ([persistence] Corrupt workspace session for host …, using defaults). A partition built field-by-field failed activeRepoId: required;
copying the whole local session and re-keying its worktree-keyed maps is what
makes the row survive long enough to be a test of anything.
Two things a userData rollback cannot answer
- The old-client empty-publish skew
(
workspace-session.ssh-host-partition-round-trip) is a client/host wire disagreement: an older client reads only the local partition and publishes areplace-sessionnaming the workspace with no tabs. Reproducing it needs two paired runtimes, not one userData directory read twice. - Relay protocol-version negotiation is likewise a wire surface. A packaged rollback with no pairing never opens a relay connection, so it exercises neither the version check nor its refusal path.
Practical notes
- A packaged build takes Chromium's
--user-data-dir;configureDevUserDataPathonly overrides userData for dev and E2E, so an isolated profile needs no special build. autoDownloadis off andautoInstallOnAppQuitis Linux-non-root only, so a packaged test instance will not install an update over the host's own app. Do not run the NSIS installer to obtain the old build — build the tag instead.- Each packaged build copies itself to
%LOCALAPPDATA%\Orca\daemon-host\<version>on first boot. That is outside the isolated userData and has to be cleaned up by hand; match the copy'sOrca.exehash against the build before removing one.