bdb4cfd35e
Address helix4u's review: - finish() now delivers the outcome BEFORE publishing it: mac bundle swap and the linux relaunch gate run first, then the result file, marker removal, and the shim event -- the app launch itself goes last so it can't race the result write. A gated/skewed linux install (AppImage/ deb/rpm, broken sandbox helper) surfaces its message in the result file AND holds the shim window open with it instead of closing on a false 'Opening Hermes...'. - mac swap is transactional with a checked rollback; a failed install restores the previous bundle and the result says so (exit 7 when even rollback fails). Failed 'open' rewrites the result truthfully. - linux gate is an exact port of the deleted update-relaunch.ts logic: anchored path-segment match on <root>/apps/desktop/release/linux-unpacked, chrome-sandbox absent = namespace build = fine, present = root+setuid required, with the real opt-outs (ELECTRON_DISABLE_SANDBOX, --no-sandbox among replayed args, or the Desktop vouching) instead of the invented HERMES_DESKTOP_NO_SANDBOX. collectRelaunchArgs/sandboxFallbackFromEnv live in updater-process.ts again; the Desktop passes filtered launch args (after --) and --relaunch-cwd so a deep-link or --no-sandbox launch survives the update. - result/status JSON strings are escaped (git permits '"' in branch names) and the result write is atomic (tmp + rename). - coverage: resolvePosixScriptHandoff + ported helpers in updater-process.test.ts (19 pass); repro.sh gate / npm run update:repro:gate asserts the whole gate matrix and round-trips a hostile branch name through the result JSON.