Files
orca/docs/reference/windows-packaged-rollback.md

77 lines
4.1 KiB
Markdown

# 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.199` tag
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 a
`replace-session` naming 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`; `configureDevUserDataPath`
only overrides userData for dev and E2E, so an isolated profile needs no
special build.
- `autoDownload` is off and `autoInstallOnAppQuit` is 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's
`Orca.exe` hash against the build before removing one.