Repository navigation
fix(orcad): replace a stale terminal daemon once it drains on Linux and WSL hosts - #31235
Conversation
…nd WSL hosts A daemon forked by an older orcad (before #31135, at umask 077) kept serving new terminals after an upgrade if it was busy at startup, because the runtime stale-bundle recycle was macOS-only. orcad now opts in on every platform; the replacement still waits for exactly zero live sessions and treats an unverifiable count as keep.
📝 Walkthrough
Priority: ➖ Normal Merge Risk: 🔵 Low · up to
|
There was a problem hiding this comment.
🧹 Nitpick comments: 1
src/main/daemon/daemon-init-restart-sequence.test.ts: 1
260-260: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winPin both opt-in tests to Linux before provider initialization.
initDaemonPtyProvider()resolves the recycle version during initialization. The restart test changesprocess.platformafterward, and the provider-installation test does not override it. On macOS, both tests can pass through the existing macOS behavior even ifrecycleStaleDaemonOnEveryPlatformis ignored.Set Linux before initialization in both tests. Restore the original platform in a
finallyblock that covers initialization and restart. This improves cross-platform coverage; it does not indicate a current production failure.
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Repository UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
5b41582d-3ed6-4fce-aec6-6f6b4688d697
📒 Files selected for processing: 11
src/main/daemon/daemon-init-dependency-mocks.tssrc/main/daemon/daemon-init-mock-types.tssrc/main/daemon/daemon-init-provider-installation.test.tssrc/main/daemon/daemon-init-restart-sequence.test.tssrc/main/daemon/daemon-launch-paths.tssrc/main/daemon/daemon-out-of-process-launcher.tssrc/main/daemon/daemon-provider-init.tssrc/main/daemon/daemon-provider-restart.tssrc/main/daemon/daemon-spawner.tssrc/main/orcad/orcad-daemon-supervision.test.tssrc/main/orcad/orcad-daemon-supervision.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 3 remain after this review.
ELI5
#31135 fixed the Orca server on SSH machines so files it creates are no longer private-only. The program that keeps your terminals alive (the terminal daemon) was usually started by the old server, so it still has the old "make everything private" setting. Every terminal it starts inherits that setting. Orca already swaps out an outdated daemon when the server starts, but only if no terminal is open at that moment. If you had a terminal open, the old daemon stayed. On Linux and WSL machines it then stayed forever, even after you closed every terminal. Now, once the old daemon has no terminals left, Orca swaps it out right before it starts your next terminal. It never touches a daemon that still has terminals running.
What Changed
Before: a remote orcad could replace an outdated terminal daemon in two places:
prepareDaemonReplacement,stale_bundlebranch): only if the daemon had exactly zero live sessions. This already worked on every platform.replaceStaleBundleDaemonBeforeNewPty): this is the path that catches a daemon that was busy at startup and has since drained. It was enabled only whereresolvePackagedDarwinAppVersion()returned a version, which means macOS only.So on Linux and WSL hosts, a daemon forked by a pre-#31135 orcad (umask
077) kept hosting every new terminal after the upgrade if any terminal was open when orcad restarted. Those terminals created owner-only files until the daemon happened to die.After:
DaemonLaunchPolicygets an optionalrecycleStaleDaemonOnEveryPlatform, andstartOrcadDaemonsets it.resolveStaleDaemonRecycleVersion(onEveryPlatform)replacesresolvePackagedDarwinAppVersion. It returns the app version on every platform when that flag is set, and keeps the darwin-only rule for the desktop.initDaemonPtyProviderand stored on theDaemonSpawner.restartDaemonreuses that spawner, so the choice survives a restart.The swap rules don't change. The existing
replaceStaleBundleDaemonOnceswaps only when:appVersiondiffers from orcad'sORCA_VERSION(an unverifiable PID record counts as not stale), andlistSessionsanswers with zero alive sessions, and the adapter tracks none either.If the session count can't be read, the daemon is kept, so an unverifiable state never leads to a swap. A daemon with any live session is kept. Nothing ever forces a restart, and there is no UI.
Why
appVersionsits in its PID record and in the hello identity. Every orcad build that contains fix(orcad): run the remote daemon at the login umask so worktrees it creates are not owner-only #31135 has a newer version than every daemon forked before it, so "stale version" is a reliable superset of "pre-fix daemon". Reading/proc/<pid>/statusUmask:would only work on Linux, could not run on macOS, and would add a second, parallel staleness rule. A version check covers every platform with the record the code already verifies.stale_bundle) already exist and run on macOS desktops. This PR only lets orcad switch it on.setsidlaunch is a Linux orcad) now get it.Linked Issue
Follow-up to #31135 (no separate issue).
Visual Proof
N/A: there is no UI. The change decides which daemon process hosts the next new terminal on a remote host.
Testing
orcad-daemon-supervision.test.ts: orcad's policy opts in, including onlinux. 3 tests fail on main.daemon-init-provider-installation.test.ts:null.daemon-init-restart-sequence.test.ts: the opt-in survivesrestartDaemon. This fails on main on Linux CI.daemon-pty-adapter-daemon-recovery.test.tsalready covers the swap itself: it swaps only at zero sessions and keeps the daemon when the count is unverifiable or positive.pnpm test src/main/daemon src/main/orcadwith one worker: 3621 passed. 23 tests fail locally inshell-ready,repro-13767andorcad-forked-child-paths, and the same 23 fail with main's sources: they depend on the developer's real shell and on macOS/privatepath resolution.e2e.ymldispatch,ssh on managed orcad (Docker)), covering terminal journeys, retained upgrade state, idle exit and terminal root owner: passed on14f8382(run 39502482172). Passed again on the final head30cbc26(run 39504705041).Review
3be5039): clean.linuxso it fails on base on every host: done.packagedAppVersion.Agent skill upstream boundary
Notes
appVersionwere already treated as stale.Checklist
N/Awith reasonpnpm lint,pnpm typecheck,pnpm test, andpnpm buildpass (or CI will cover; local preferred)