Skip to content

fix(mac): keep launch-at-login app running#102465

Merged
steipete merged 4 commits into
mainfrom
codex/fix-mac-launch-agent-reload
Jul 9, 2026
Merged

fix(mac): keep launch-at-login app running#102465
steipete merged 4 commits into
mainfrom
codex/fix-mac-launch-agent-reload

Conversation

@steipete

@steipete steipete commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

Fixes an issue where users launching the macOS app at login could have the app unload itself during startup when the launch-at-login toggle hydrated from launchd state.

Why This Change Was Made

The app now refreshes the persisted launch-agent plist while treating an already-loaded job as active state, skipping only the destructive bootout/bootstrap cycle. The loaded-state check queries launchd independently from plist presence, preserving the normal off/on toggle path.

User Impact

The macOS app remains running after launch-at-login startup instead of disappearing and leaving its login job unloaded.

Evidence

  • Before: bootstrapping ai.openclaw.mac launched the app, which rewrote its plist, booted itself out, exited, and left no loaded job.
  • After: a signed release app launched from the same agent remained state = running with one OpenClaw process and the plist still present after startup hydration.
  • swift test --package-path apps/macos --filter LaunchAgentManagerTests — 7 tests passed.
  • .agents/skills/autoreview/scripts/autoreview --mode local --stream-engine-output — clean; no accepted/actionable findings.

@steipete steipete self-assigned this Jul 9, 2026
@openclaw-barnacle openclaw-barnacle Bot added the maintainer Maintainer-authored PR label Jul 9, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 519dd99247

ℹ️ 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".

Comment thread CHANGELOG.md Outdated

### Fixes

- **macOS launch at login:** keep an already-loaded Mac app job running while status hydration refreshes its plist, preventing startup from unloading itself.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Remove the unreleased changelog edit

AGENTS.md says CHANGELOG.md is release-only and should not be edited for normal fixes because release generation owns it. This commit is a normal macOS fix, so landing this manual entry risks release-note drift or duplication when the generated changelog is produced; keep the release-note context in the commit/PR body instead.

Useful? React with 👍 / 👎.

@clawsweeper

clawsweeper Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 9, 2026, 2:48 AM ET / 06:48 UTC.

Summary
This PR updates the macOS LaunchAgent enable path to refresh the plist but skip bootout/bootstrap/kickstart when the app job is already loaded, and adds a Swift test for that branch.

PR surface: Other +32. Total +32 across 2 files.

Reproducibility: yes. source inspection gives a high-confidence path: AppState can hydrate launchAtLogin after initialization and call the current enable path, which bootout/bootstrap/kickstarts an already loaded app job. I did not run a live macOS login-cycle reproduction in this read-only review.

Review metrics: 1 noteworthy metric.

  • LaunchAgent enable path: 1 lifecycle path changed. The enable path now skips bootout/bootstrap/kickstart when launchd already reports the app job loaded, so maintainers should notice the live launchd behavior change before merge.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🐚 platinum hermit
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P2] Get the exact-head CI rollup green, including the failing native-i18n job, before merge.

Risk before merge

  • [P1] The current CI rollup includes a native-i18n failure and the branch is behind base, so landing should wait for normal exact-head maintainer/CI gates even though no code-level defect was found in the reviewed diff.

Maintainer options:

  1. Decide the mitigation before merge
    Land the focused LaunchAgentManager change after maintainer review and exact-head macOS/CI gates, keeping release-note context in PR or merge metadata rather than CHANGELOG.md.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • [P2] Protected maintainer labeling and current CI state put this in normal maintainer merge handling; this review found no narrow automated repair to queue.

Security
Cleared: The diff only changes internal Swift LaunchAgent lifecycle code and a focused test; it does not change workflows, dependencies, lockfiles, secrets, package resolution, or downloaded execution paths.

Review details

Best possible solution:

Land the focused LaunchAgentManager change after maintainer review and exact-head macOS/CI gates, keeping release-note context in PR or merge metadata rather than CHANGELOG.md.

Do we have a high-confidence way to reproduce the issue?

Yes, source inspection gives a high-confidence path: AppState can hydrate launchAtLogin after initialization and call the current enable path, which bootout/bootstrap/kickstarts an already loaded app job. I did not run a live macOS login-cycle reproduction in this read-only review.

Is this the best way to solve the issue?

Yes, this is the best fix shape among the inspected options: keeping the loaded-job guard inside LaunchAgentManager preserves the launchd owner boundary and covers startup hydration without adding AppState-specific suppression.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 5f91f6c95840.

Label changes

Label changes:

  • add P2: This is a focused macOS startup reliability fix with limited blast radius to users who enable Launch at login.
  • add proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes before/after signed release app launch-agent proof with the after state running, one process present, and the plist still present, plus focused Swift test output; no contributor proof action is needed.
  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body includes before/after signed release app launch-agent proof with the after state running, one process present, and the plist still present, plus focused Swift test output; no contributor proof action is needed.

Label justifications:

  • P2: This is a focused macOS startup reliability fix with limited blast radius to users who enable Launch at login.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body includes before/after signed release app launch-agent proof with the after state running, one process present, and the plist still present, plus focused Swift test output; no contributor proof action is needed.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes before/after signed release app launch-agent proof with the after state running, one process present, and the plist still present, plus focused Swift test output; no contributor proof action is needed.
Evidence reviewed

PR surface:

Other +32. Total +32 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 0 0 0 0
Tests 0 0 0 0
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 2 34 2 +32
Total 2 34 2 +32

What I checked:

Likely related people:

  • steipete: Merged the earlier Launch at login startup guard PR and appears in the macOS app launch/history trail beyond authoring this PR. (role: introduced behavior and current macOS owner signal; confidence: high; commits: 1985790f7f2a, 9a7160786a7d; files: apps/macos/Sources/OpenClaw/AppState.swift, apps/macos/Sources/OpenClaw/LaunchAgentManager.swift)
  • wes-davis: Authored the earlier fix preventing launch-at-login plist deletion during app startup, which is adjacent to this startup hydration side effect. (role: prior related bug fixer; confidence: medium; commits: 6f5503688dc8; files: apps/macos/Sources/OpenClaw/AppState.swift)
  • stablegenius49: Authored the merged KeepAlive removal and plist helper/test coverage on the same app LaunchAgent surface. (role: recent adjacent contributor; confidence: medium; commits: 40f6be315868; files: apps/macos/Sources/OpenClaw/LaunchAgentManager.swift, apps/macos/Tests/OpenClawIPCTests/LaunchAgentManagerTests.swift)
  • ImLukeF: Merged the prior macOS app LaunchAgent KeepAlive fix that shaped the current plist helper and test surface. (role: reviewer and merger of adjacent fix; confidence: medium; commits: 40f6be315868; files: apps/macos/Sources/OpenClaw/LaunchAgentManager.swift, apps/macos/Tests/OpenClawIPCTests/LaunchAgentManagerTests.swift)
  • Vincent Koc: Current blame for the central files points through a recent broad commit, but the commit topic is unrelated to launch-at-login behavior. (role: recent file carrier; confidence: low; commits: aad99747cd45; files: apps/macos/Sources/OpenClaw/AppState.swift, apps/macos/Sources/OpenClaw/LaunchAgentManager.swift)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P2 Normal backlog priority with limited blast radius. labels Jul 9, 2026
@steipete
steipete merged commit 363cf04 into main Jul 9, 2026
44 checks passed
@steipete
steipete deleted the codex/fix-mac-launch-agent-reload branch July 9, 2026 07:08
@steipete

steipete commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 9, 2026
* fix(mac): avoid launch-agent self-reload

* chore: leave release changelog generation

* style(mac): use conditional expression
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: macos App: macos maintainer Maintainer-authored PR P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: XS status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant