fix(server): wait for launchd shutdown safely - #7874
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7eaa23c233
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
ApprovabilityVerdict: Skipped Macroscope did not run approvability analysis for this PR. Macroscope could not determine whether this PR modifies its approvability configuration, so the PR was not approved automatically. A PR that may change the rules that govern approval is never approved automatically. |
7eaa23c to
7c5adc4
Compare
|
@codex review |
|
Codex Review: Didn't find any major issues. Chef's kiss. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
LastCode inherits the same macOS background-service lifecycle race as upstream: `launchctl bootout` can return before the old job finishes draining, while the prior unsupported `--wait` form and optional-error handling can let reinstall proceed without proving the job is gone. This is the patch-identical LastCode port of [upstream PR pingdotgg#7874](pingdotgg#7874), from upstream commit [`7c5adc45ea3ee7456e04339430c2433e3486ffd7`](7c5adc4). It uses supported `launchctl bootout`, polls the exact service with `launchctl print` until launchd confirms absence, and fails closed on timeout, permission, domain, or unexpected-output errors before enabling and bootstrapping. Provenance: - upstream commit: `7c5adc45ea3ee7456e04339430c2433e3486ffd7` - stable patch ID: `e5e07203e79b88a6051cc6eea2159118e4486604` - LastCode port commit: `f52d715a97460fca99afaebc522788a85a8ae1c0` Progresses #39. Validation: - 21 focused boot-service tests - server typecheck - targeted lint, formatting, and diff checks - guarded `pnpm lastcode:ci:quick` pre-push gate Implemented by OpenAI Codex (GPT-5.6) in the T3 Code Codex harness.
LastCode inherits the same macOS background-service lifecycle race as upstream: `launchctl bootout` can return before the old job finishes draining, while the prior unsupported `--wait` form and optional-error handling can let reinstall proceed without proving the job is gone. This is the patch-identical LastCode port of [upstream PR pingdotgg#7874](pingdotgg#7874), from upstream commit [`7c5adc45ea3ee7456e04339430c2433e3486ffd7`](7c5adc4). It uses supported `launchctl bootout`, polls the exact service with `launchctl print` until launchd confirms absence, and fails closed on timeout, permission, domain, or unexpected-output errors before enabling and bootstrapping. Provenance: - upstream commit: `7c5adc45ea3ee7456e04339430c2433e3486ffd7` - stable patch ID: `e5e07203e79b88a6051cc6eea2159118e4486604` - LastCode port commit: `f52d715a97460fca99afaebc522788a85a8ae1c0` Progresses #39. Validation: - 21 focused boot-service tests - server typecheck - targeted lint, formatting, and diff checks - guarded `pnpm lastcode:ci:quick` pre-push gate Implemented by OpenAI Codex (GPT-5.6) in the T3 Code Codex harness.
LastCode inherits the same macOS background-service lifecycle race as upstream: `launchctl bootout` can return before the old job finishes draining, while the prior unsupported `--wait` form and optional-error handling can let reinstall proceed without proving the job is gone. This is the patch-identical LastCode port of [upstream PR pingdotgg#7874](pingdotgg#7874), from upstream commit [`7c5adc45ea3ee7456e04339430c2433e3486ffd7`](7c5adc4). It uses supported `launchctl bootout`, polls the exact service with `launchctl print` until launchd confirms absence, and fails closed on timeout, permission, domain, or unexpected-output errors before enabling and bootstrapping. Provenance: - upstream commit: `7c5adc45ea3ee7456e04339430c2433e3486ffd7` - stable patch ID: `e5e07203e79b88a6051cc6eea2159118e4486604` - LastCode port commit: `f52d715a97460fca99afaebc522788a85a8ae1c0` Progresses #39. Validation: - 21 focused boot-service tests - server typecheck - targeted lint, formatting, and diff checks - guarded `pnpm lastcode:ci:quick` pre-push gate Implemented by OpenAI Codex (GPT-5.6) in the T3 Code Codex harness.
LastCode inherits the same macOS background-service lifecycle race as upstream: `launchctl bootout` can return before the old job finishes draining, while the prior unsupported `--wait` form and optional-error handling can let reinstall proceed without proving the job is gone. This is the patch-identical LastCode port of [upstream PR pingdotgg#7874](pingdotgg#7874), from upstream commit [`7c5adc45ea3ee7456e04339430c2433e3486ffd7`](7c5adc4). It uses supported `launchctl bootout`, polls the exact service with `launchctl print` until launchd confirms absence, and fails closed on timeout, permission, domain, or unexpected-output errors before enabling and bootstrapping. Provenance: - upstream commit: `7c5adc45ea3ee7456e04339430c2433e3486ffd7` - stable patch ID: `e5e07203e79b88a6051cc6eea2159118e4486604` - LastCode port commit: `f52d715a97460fca99afaebc522788a85a8ae1c0` Progresses #39. Validation: - 21 focused boot-service tests - server typecheck - targeted lint, formatting, and diff checks - guarded `pnpm lastcode:ci:quick` pre-push gate Implemented by OpenAI Codex (GPT-5.6) in the T3 Code Codex harness.
LastCode inherits the same macOS background-service lifecycle race as upstream: `launchctl bootout` can return before the old job finishes draining, while the prior unsupported `--wait` form and optional-error handling can let reinstall proceed without proving the job is gone. This is the patch-identical LastCode port of [upstream PR pingdotgg#7874](pingdotgg#7874), from upstream commit [`7c5adc45ea3ee7456e04339430c2433e3486ffd7`](7c5adc4). It uses supported `launchctl bootout`, polls the exact service with `launchctl print` until launchd confirms absence, and fails closed on timeout, permission, domain, or unexpected-output errors before enabling and bootstrapping. Provenance: - upstream commit: `7c5adc45ea3ee7456e04339430c2433e3486ffd7` - stable patch ID: `e5e07203e79b88a6051cc6eea2159118e4486604` - LastCode port commit: `f52d715a97460fca99afaebc522788a85a8ae1c0` Progresses #39. Validation: - 21 focused boot-service tests - server typecheck - targeted lint, formatting, and diff checks - guarded `pnpm lastcode:ci:quick` pre-push gate Implemented by OpenAI Codex (GPT-5.6) in the T3 Code Codex harness.
What Changed
launchctl bootout <service-target>formlaunchctl printto confirm the exact job has left the user domain before enabling and bootstrapping it againWhy
launchctl bootoutcan return while a job is still honoring its plist shutdown timeout. Immediately bootstrapping the replacement can then race the draining process and fail. The prior--waitargument is not a supported launchctl option, and treating stop/enable failures as optional could hide real lifecycle failures.This keeps install and uninstall deterministic without changing the service definition or launching anything during tests.
Validation
Checklist
LastCode counterpart: lastobelus/lastCode#56.
Implemented by OpenAI Codex (GPT-5.6) in the T3 Code Codex harness.
Note
Medium Risk
Changes macOS launch-agent stop/start sequencing, which can affect background service install, repair, and uninstall if launchctl output or timing is misclassified.
Overview
Stops racing a draining macOS launch agent on reinstall.
launchctl bootoutno longer uses the unsupported--waitflag; the flow pollslaunchctl printuntil launchd confirms the exact job left the user domain (or 120s timeout).Optional stop/enable steps are gone. Already-absent is treated as success only on launchd’s exact not-loaded / no-such-process messages. Permission, missing-domain (on install), unexpected print output, and timeout now fail closed with a clearer
BootServiceCommandError. Uninstall still succeeds when the GUI domain itself is missing.Reviewed by Cursor Bugbot for commit 7c5adc4. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Replace
launchctl bootout --waitwith polling verification inBootService--waitflag fromlaunchctl bootout(not supported by macOS) and replaces it with explicit polling oflaunchctl printuntil launchd confirms the agent is absent, bounded bySTOP_STEP_TIMEOUT(120s)isConfirmedLaunchdNotLoadedandisConfirmedLaunchdBootoutNotLoadedto distinguish benign not-loaded responses from real errors by exact stderr/stdout text matchingoptionalstep flag with a taggedoperation: 'launchd-bootout'union carryingverifyAbsentmetadata;runLaunchdBootoutdispatches bootout, tolerates only specific not-loaded conditions, then polls for confirmationtimedOutfield toBootServiceCommandErrorso timeout failures render a clear messageoptional: trueis removed entirely —launchctl enablefailures now abort the flow instead of being ignored; allBootServiceStepcall sites must specifyoperation: 'launchd-bootout'withverifyAbsentdata for launchd stop stepsMacroscope summarized 7c5adc4.