fix(desktop): scope agent sweep to the owning app instance#808
Merged
Conversation
aa866b0 to
304982f
Compare
wpfleger96
approved these changes
Jun 1, 2026
The system-wide orphan sweep (sweep_system_agent_processes) matched any process by binary + uid + SPROUT_MANAGED_AGENT=1, with no instance scoping. With two Sprouts on one machine (e.g. a just dev build and the installed DMG), one instance's sweep would SIGTERM the other's agents. Stamp each spawned agent's SPROUT_MANAGED_AGENT marker with the spawning desktop instance's bundle identifier (xyz.block.sprout.app vs .dev), and make the sweep only reap agents carrying this instance's id. The identifier is stable across restarts, so an instance still recognizes its own previously-spawned agents while never touching another live Sprout's. Co-authored-by: Brain <21994759fc7a6fa6b965551d35cfd7897d262f2495467f2d78694ddcfa6a5c7e@sprout-oss.stage.blox.sqprod.co> Signed-off-by: Wes <wesbillman@users.noreply.github.com>
304982f to
893feb6
Compare
tlongwell-block
pushed a commit
that referenced
this pull request
Jun 1, 2026
* origin/main: feat(desktop): keyboard shortcuts — ⌘⇧N new channel + ↑-to-edit last message (#809) fix(desktop): scope agent sweep to the owning app instance (#808) Signed-off-by: tlongwell-block <109685178+tlongwell-block@users.noreply.github.com> # Conflicts: # desktop/scripts/check-file-sizes.mjs
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.
Problem
When two Sprout desktop instances run on the same machine — e.g. a
just devbuild alongside the installed DMG (the standard dogfooding setup) — one instance's cleanup kills the other instance's agents. Symptom: agents stop unexpectedly, all at once, when the dev instance reloads or quits.Root cause
sweep_system_agent_processes(the machine-wide orphan safety net) matches agent processes purely on binary name + same uid + envSPROUT_MANAGED_AGENT=1. There is no scoping by which desktop instance spawned them, so a dev instance happily SIGTERMs the DMG instance's agents (and vice versa) — they match all three criteria.The PID-file-based sweep (
sweep_orphaned_agent_processes) is already correctly instance-scoped (dev and prod have different bundle identifiers → separateapp_data_dir→ separateagent-pids/receipt dirs). This machine-wide scan was the one hole.Fix
Give each agent an ownership stamp and make the sweep refuse to reap agents that aren't ours:
SPROUT_MANAGED_AGENT=<app-identifier>at spawn instead of=1. The app identifier (xyz.block.sprout.appfor release,xyz.block.sprout.app.devfor dev) is stable across restarts, so a relaunched instance still recognizes and can reclaim its own prior agents while never matching another instance's.process_has_sprout_marker(both macOSKERN_PROCARGS2and Linux/proc/environpaths) now takes the current instance id and only matches agents carrying that id.current_instance_id(app)and a sharedsprout_marker_entry()helper so the spawn stamp and the sweep matcher can never drift apart.lib.rsquit path,restore.rsstartup path) pass the instance id.Ownership becomes a property the agent carries, not a question we poll — so no racy "is another Sprout still alive?" probing.
Verification
just desktop-tauri-checkcleanjust desktop-tauri-clippyclean with-D warnings(--all-targets)just desktop-tauri-test— 416 passed / 0 failed, including a newmarker_entry_is_namespaced_by_instance_idtest pinning the marker formatNotes / out of scope
check-file-sizes.mjsoverride forruntime.rsis bumped 1300→1330 (the file was already at its limit; +40 lines tipped it over). Rationale comment extended.RunEvent::ExitRequestedand kills all agents. Real, but not the trigger here and out of scope for this PR — flagging for a possible follow-up.