Uh oh!
There was an error while loading. Please reload this page.
feat(#430): macOS lifecycle — login autostart, no-admin IT remedy, first-launch prompt - #526
Conversation
…-launch prompt
macOS had the weakest lifecycle of the three OSes: no autostart at all (a rebooted
headless Mac stayed down until someone re-ran manually), the up-front admin gate failed
managed/no-admin users with a generic sudo error, and Docker Desktop's privileged-helper
dialog was never mentioned.
- _install_macos_autostart: writes a per-user LaunchAgent (no admin needed) that starts
the runtime at each login — `open -a Docker` on a GUI Mac, `colima start` on a headless
one — with RunAtLoad. Combined with the k3d --restart unless-stopped policy, a rebooted
Mac (GUI or headless) returns with ZERO human action. Best-effort; sets
TB_MACOS_AUTOSTART=1 so the summary can honestly promise it.
- _macos_require_admin (+ _macos_user_is_admin): fail FAST on a no-admin Mac with a named,
IT-facing remedy (the macOS analog of Linux prepare-host) instead of preflight_sudo's
generic "sudo authentication failed" after a wasted prompt. Admins/root pass through.
- First-launch: name the privileged-helper prompt ("macOS asks for your admin password
once") alongside the license note, so the auth dialog isn't a surprise.
- summary _reboot_note: macOS now says "restarts automatically (login item configured)"
when autostart is set; the no-autostart output is byte-identical (golden-safe).
Tests: new scripts/tests/setup-macos-lifecycle.bats (admin detection, no-admin remedy,
LaunchAgent GUI/headless/best-effort-failure, reboot-note both ways). Separate file from
setup-macos.bats / setup-macos-arch.bats to avoid a file-add clash across parallel PRs.
shellcheck/style/drift clean; summary + copy-catalog golden green; manifest regenerated.
Closes#430
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>…cycle # Conflicts: # scripts/lib/setup-macos.sh # scripts/manifest.sha256
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…gbot) Two Bugbot findings: 1. (Medium) _install_macos_autostart returns 1 on a mkdir/write failure and install_macos called it BARE under set -e — aborting the whole install after Docker + tools were already in, contradicting the best-effort contract. Call it with `|| true`. New test drives install_macos with a failing autostart and asserts it still exits 0. 2. (High) The no-admin remedy was inaccurate: re-running as the same non-admin account just hits _macos_require_admin again, and there is NO macOS prepare-host (run_prepare_host errors on Darwin). Rewrote it to name the remedies that actually unblock the install — grant THIS account admin rights (then re-run as yourself), or install from an account that already has admin. Dropped the misleading "install Docker + re-run" loop and the nonexistent prepare-host reference. Test updated accordingly. shellcheck/style clean; 10/10 setup-macos-lifecycle.bats; manifest regenerated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…UTOSTART (Bugbot) Two more Bugbot findings: 1. (High) A per-user LaunchAgent only loads inside a GUI/Aqua login session — which a HEADLESS Mac never has — so the headless branch wrote an agent that never runs at boot, making the "restarts automatically" promise false. Headless now installs a system LaunchDaemon (/Library/LaunchDaemons, root) that runs `colima start` at BOOT as the install user, with HOME + PATH set (a boot daemon has no user env). GUI keeps the LaunchAgent. Factored the shared plist skeleton into _emit_launch_plist. 2. (Medium) _install_macos_autostart ignored TRACEBLOC_NO_AUTOSTART, the opt-out that already gates ensure_cluster_autostart (Linux) and the Windows peer. It now short- circuits on that flag, so macOS no longer configures autostart or promises auto- restart when the operator opted out. Tests: headless test now asserts a LaunchDaemon (UserName + EnvironmentVariables + sudo launchctl, boot not login); new opt-out test; GUI + best-effort tests unchanged. 11/11 setup-macos-lifecycle.bats; shellcheck/style/drift clean; manifest regenerated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Two more Bugbot findings on the LaunchDaemon change: 1. (Medium) Both plists logged to a fixed /tmp/tracebloc-autostart.log. With the installer's umask 077 the first account creates it 0600, so a second account's job can't open it (EX_CONFIG → runtime never starts), and /tmp is symlink-plantable on a shared Mac. _emit_launch_plist now takes a per-user log path: the LaunchAgent logs to $HOME/Library/Logs and the LaunchDaemon to the install user's ~/Library/Logs. 2. (Low) _reboot_note said "login item configured" for every macOS autostart, but a headless install uses a system LaunchDaemon (/Library/LaunchDaemons), not a login item — so IT would look in the wrong place. Dropped the mechanism label: "After a reboot, tracebloc restarts automatically." (accurate for both agent and daemon). Tests: assert the plist log path is per-user (Library/Logs), not /tmp; summary + copy-catalog golden green (no-autostart line unchanged). shellcheck clean; manifest regen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
… (Bugbot)
Two more Bugbot findings on the headless LaunchDaemon:
1. (High) The daemon's StandardOutPath is ~/Library/Logs/... but that dir was never
created (the GUI path mkdir's its own). On a fresh headless account without
~/Library/Logs, launchd fails EX_CONFIG before colima runs, yet TB_MACOS_AUTOSTART=1
still promised recovery. Now mkdir -p "${_home}/Library/Logs" before writing the plist.
2. (High) The daemon ran a bare oneshot `colima start` at boot with no retry — the
VZ+Rosetta stack commonly leaves stale VM state across a reboot, so the first start
fails and the edge never comes back. Replaced with a resilient wrapper:
/bin/bash -c 'until colima start; retry up to 3x, colima stop + sleep 15 between
attempts' — force-stopping clears the stale state. Loop body has no </>/& so it stays
valid inside the plist <string>.
Tests: headless test now asserts the log dir is created, the /bin/bash resilient wrapper,
and colima stop (retry). 11/11 setup-macos-lifecycle.bats; shellcheck/style clean; manifest regen.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>Uh oh!
There was an error while loading. Please reload this page.
…e (Bugbot) The headless LaunchDaemon retry ran a bare `colima stop` between failed starts, but the intent is a FORCE stop: without --force, orphaned VZ driver state isn't cleared (and a bare stop can hang), so all three attempts fail and a rebooted headless Mac stays down despite TB_MACOS_AUTOSTART=1. Use `colima stop --force`. Test asserts the flag. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 58203d0. Configure here.
Uh oh!
There was an error while loading. Please reload this page.
…ve its real path (Bugbot) Headless autostart always wrote a colima LaunchDaemon and set TB_MACOS_AUTOSTART=1, but install_docker_desktop installs colima only when Docker was DOWN — if Docker was already up by other means colima may be absent, so the daemon was bogus and the auto-restart promise false. The `|| echo /usr/local/bin/colima` fallback also baked a path that's wrong on Apple Silicon (Homebrew there is /opt/homebrew/bin). Now resolve colima via `command -v` (its REAL path on either chip) and, if it isn't installed, skip autostart honestly (best-effort return 1; caller's `|| true`) so the summary won't promise recovery via a runtime that isn't there. New test: headless + colima absent -> skip, no daemon, flag unset. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
LukasWodka
commented
Aug 3, 2026
/fr-pass |

#430 — macOS lifecycle: autostart, first-launch prompt, no-admin path
macOS had the weakest lifecycle story of the three OSes:
--restart unless-stoppedpolicy is useless until the runtime itself starts.sudo authentication failed, not a path forward.Fix
1. Login autostart —
_install_macos_autostartWrites a per-user LaunchAgent (
~/Library/LaunchAgents/io.tracebloc.runtime.plist, no admin needed) withRunAtLoadthat starts the runtime at each login:open -a Dockercolima startCombined with the k3d
--restart unless-stoppedpolicy, a rebooted Mac (GUI or headless) returns with zero human action. Best-effort (never fails the install); setsTB_MACOS_AUTOSTART=1.2. No-admin named remedy —
_macos_require_adminFails fast on a no-admin Mac with a named, IT-facing remedy (the macOS analog of Linux prepare-host) — install Docker Desktop + grant access, grant admin rights, or have IT run the installer once — instead of
preflight_sudo's generic error after a wasted password prompt. Admins/root pass straight through.3. First-launch prompt
Names the privileged-helper dialog ("macOS asks for your admin password once") alongside the license note, so the auth prompt isn't a surprise.
4. Summary
_reboot_notenow says "After a reboot, tracebloc restarts automatically (login item configured)" when autostart is set; the no-autostart output is byte-identical (golden-safe).Acceptance criteria
Tests / gates
scripts/tests/setup-macos-lifecycle.bats(9): admin detection, no-admin remedy, LaunchAgent GUI/headless/best-effort-failure, reboot-note both ways.setup-macos.bats/setup-macos-arch.batsto avoid a file-add clash across parallel PRs.shellcheck --severity=error, check-style, check-drift clean;summary.bats+copy-cataloggolden green (default output unchanged);manifest.sha256regenerated (R8).Note: bash-3.2-safe (never-empty arg arrays; no namerefs).
Closes#430
Note
Medium Risk
Writes LaunchAgents/Daemons and uses sudo for headless boot autostart; failures are best-effort but misconfiguration could affect post-reboot runtime on shared or headless Macs.
Overview
Improves the macOS installer so reboots and non-admin accounts are handled explicitly instead of leaving users to manually restart Docker or hit a vague sudo failure.
Autostart adds
_install_macos_autostart(best-effort,|| trueunderset -e): a GUI Mac gets a per-user LaunchAgent that runsopen -a Dockerat login; headless installs a system LaunchDaemon that runs colima as the install user with retry/colima stop --force, but only when colima is actually present. HonorsTRACEBLOC_NO_AUTOSTART; setsTB_MACOS_AUTOSTART=1only on success.Admin gate runs
_macos_require_adminbeforepreflight_sudoso standard/managed accounts fail fast with IT-facing steps (grant admin or install from an admin account), not a generic sudo error.UX: first-time Docker Desktop setup now mentions the privileged-helper password prompt.
_reboot_notepromises automatic restart whenTB_MACOS_AUTOSTART=1; otherwise the “open Docker Desktop” line is unchanged.Adds
setup-macos-lifecycle.batsand updatesmanifest.sha256.Reviewed by Cursor Bugbot for commit 6e37fc2. Bugbot is set up for automated code reviews on this repo. Configure here.