fix(runtimed): use in-bundle sidecar binary for launchd on macOS#1256
Merged
fix(runtimed): use in-bundle sidecar binary for launchd on macOS#1256
Conversation
…andalone copy The daemon was being copied from the nteract.app bundle to ~/.local/share/runt/bin/runtimed during installation. The launchd plist pointed to this standalone copy, which triggered macOS's "App Management" permission dialog and caused code-signature crashes during upgrades. Now on macOS, the launchd plist points directly at the binary inside the app bundle (e.g., /Applications/nteract.app/Contents/MacOS/runtimed). This eliminates: - The App Management permission prompt - The quarantine-stripping hack - The entire class of code-signature-invalidation bugs during upgrades Existing installations are migrated automatically on the next app launch (via the upgrade flow) or manually via `runt daemon doctor --fix`. Changes: - runt-workspace: Add migration helpers (legacy_standalone_binary_path, bundled_daemon_binary_path, plist_binary_path, is_legacy_standalone_install) - service.rs: default_binary_path() prefers in-bundle path; install/upgrade skip binary copy for in-bundle; uninstall won't delete in-bundle binary; cleanup_legacy_binary() removes old standalone copy - runt doctor: New standalone_binary check detects legacy installs; --fix migrates plist to in-bundle and cleans up standalone binary; quarantine check skipped for signed in-bundle binaries
Address two review issues: P1: Doctor now reads the binary path from the installed launchd plist (what launchd actually runs) rather than default_binary_path() (what we'd prefer to install). This ensures a legacy standalone install gets diagnosed correctly even when an app bundle exists on disk. P2: install() and upgrade() now check the source_binary argument for the in-bundle heuristic, not self.config.binary_path. When source_binary is inside an app bundle, binary_path is set to it for the plist. When a custom path is passed (e.g., --binary /path/to/runtimed), it is honored and copied as before. Both methods now take &mut self.
default_binary_path() was resolving to the app-bundle binary for all callers on macOS (including CLI tools like `runt`). This meant a custom `runt daemon install --binary /path/to/runtimed` would try to copy into the app bundle instead of the standalone install location. Now default_binary_path() only returns the in-bundle path when current_exe() is itself inside an app bundle (sidecar context). For all other callers, it returns the standalone install path. The install()/upgrade() methods handle in-bundle detection based on the source_binary argument, not the default config path.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
~/.local/share/runt/bin/runtimed. This eliminates the macOS "App Management" permission dialog, quarantine stripping, and code-signature crashes during upgrades.runt daemon doctor --fix.runt doctorcheck (standalone_binary) detects legacy installs with[legacy]status and offers migration via--fix.--binaryinstalls —install()andupgrade()detect in-bundle vs custom based on thesource_binaryargument, not the default config path. Custom binary paths are copied to the standalone location as before.default_binary_path()(what we'd prefer to install next), so legacy installs are diagnosed correctly even when an app bundle exists.Context
The standalone copy approach was the initial design (PR #150), modeled after conventional Unix daemon patterns. PR #1056 later added atomic binary replacement to fix code-signature crashes during upgrades — but those crashes only existed because we were copying the binary out in the first place.
Test plan
runt daemon doctorshows[legacy]for existing standalone installsrunt daemon doctor --fixmigrates plist to in-bundle, cleans up standalone binaryrunt daemon install --binary /custom/pathcopies to standalone location (not into app bundle)runt daemon doctorreports error appropriately