Skip to content

fix(macos): give install_macos the Tier 0 path Linux has had since #1175 (client#703) - #704

Merged
LukasWodka merged 4 commits into
developfrom
fix/703-macos-tier0-path
Aug 13, 2026
Merged

fix(macos): give install_macos the Tier 0 path Linux has had since #1175 (client#703)#704
LukasWodka merged 4 commits into
developfrom
fix/703-macos-tier0-path

Conversation

@LukasWodka

@LukasWodkaLukasWodka commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Closes#703. Depends on nothing, but reads best after #702 (which fixed the diagnostic that pointed at the wrong line while this bug was being chased).

The bug

A Mac where a container runtime is already installed and running is classified Tier 0 — "zero root, no privileged steps". Step b then ran the admin gate and primed sudo anyway:

Host check
Container runtime Docker 29.7.2 — docker info OK ✓
Privilege regular user; sudo needs a password –
→ Install tier Tier 0 (zero root) — a container is already runnable; no privileged steps.
step b: install_macos starting (OS=Darwin ARCH=arm64 tier=0)
step b: admin check passed <- and nothing after this

It demanded an administrator password in order to install a runtime that was already installed and answering.

install_linux has short-circuited Tier 0 since RFC 0001 #1175. install_macos was a flat sequence with no tier branch at all — and install_macos_cli_tools hardcoded /usr/local/bin + sudo under the comment "macOS has no Tier/rootless model", so even skipping the admin gate would still have prompted for a password to write the tools.

The fix

At Tier 0, mirror the Linux branch:

beforeafter (Tier 0)
_macos_require_adminrunsskipped
preflight_sudorunsskipped
install_homebrewrunsskipped
install_docker_desktoprunsskipped
assert_amd64_emulationrunsruns
CLI tools target/usr/local/bin + sudo~/.local/bin, no sudo
_install_macos_autostartrunsruns (per-user LaunchAgent, no admin)

_persist_tools_on_path is called for the new target; it self-gates on ~/.local/bin and is already macOS-aware (_tools_rc_for_shell~/.zshrc for zsh, the default shell on modern macOS).

Skipping the admin gate is deliberate, not incidental. Tier 0 is precisely the case RFC 0001 opened up — a user with no administrator rights on a machine where someone else already provisioned the runtime. That user could not install at all before this.

What is deliberately unchanged

Every other tier is byte-identical — including an unsetINSTALL_TIER, which is what a stale bootstrap that never fetched probe.sh produces. That must keep the privileged path rather than silently skipping it, and there's a test pinning it.

Test plan

Seven new bats tests. The four load-bearing ones are mutation-real:

--- install_macos Tier 0 branch removed ---
not ok 11 install_macos: tier 0 skips the admin gate AND sudo priming (client#703)
not ok 12 install_macos: tier 0 skips Homebrew and the Docker Desktop install
--- cli-tools tier branch removed ---
not ok 16 install_macos_cli_tools: tier 0 targets ~/.local/bin with no sudo (client#703)

The controls (tier 2 unchanged, unset tier unchanged, tools/amd64/autostart still run) correctly keep passing under both mutations — they are there to catch an over-broad skip, not to be sensitive to this one.

  • make check green · make bats985 tests, 0 failures · manifest regenerated (both edited libs).

Field impact

This is the defect behind the report that started #681/#682. With it, that machine's step b has nothing left to fail on: Docker is up, so the entire privileged half of step b no longer runs.

🤖 Generated with Claude Code


Note

Medium Risk
Changes macOS install branching and autostart behavior for Tier 0 and headless no-sudo paths; privileged tiers are intended to stay unchanged, with tests guarding unset INSTALL_TIER.

Overview
Tier 0 on macOS now matches Linux: when INSTALL_TIER=0, install_macos skips the admin gate, sudo priming, Homebrew, and Docker Desktop, then still runs amd64 emulation check, installs pinned CLI tools, and runs autostart best-effort.

CLI tools for Tier 0 land in ~/.local/bin with no sudo (other tiers still use /usr/local/bin), PATH is updated for the current shell, and _persist_tools_on_path runs for shell persistence.

Autostart (no-sudo) is passed from Tier 0 so headless installs never write the boot LaunchDaemon via sudo; GUI LaunchAgents still install. Headless no-sudo skips with honest hints, detects an existing daemon as already configured, and sets TB_MACOS_HEADLESS_NO_AUTOSTART / optional TB_MACOS_MANUAL_RUNTIME_CMD when colima is present.

Summary footer (_reboot_note) adds a headless Tier 0 branch so the last line does not tell operators to open Docker Desktop when autostart was skipped.

Extensive BATS coverage and manifest.sha256 updates for the touched libs.

Reviewed by Cursor Bugbot for commit 1c5d12a. Bugbot is set up for automated code reviews on this repo. Configure here.

A Mac where a container runtime is already installed AND running is classified
Tier 0 — "zero root, no privileged steps" — and step b then ran the admin gate
and primed sudo anyway, demanding an administrator password to install a runtime
that was already installed and answering. A field report died exactly there:
Host check
Container runtime Docker 29.7.2 — docker info OK ✓
→ Install tier Tier 0 (zero root) — a container is already runnable.
...
step b: install_macos starting (OS=Darwin ARCH=arm64 tier=0)
step b: admin check passed <- nothing after this
install_linux has short-circuited Tier 0 since RFC 0001 #1175; install_macos was
a flat sequence with no tier branch at all, and install_macos_cli_tools
hardcoded /usr/local/bin + sudo under the comment "macOS has no Tier/rootless
model" — so even skipping the admin gate would still have prompted for a
password to write the tools.
Tier 0 now skips the admin gate, sudo priming, Homebrew and the Docker Desktop
install, and lands the pinned tools in ~/.local/bin with no sudo (the same
target _set_tools_target picks on Linux), then persists it on PATH via
_persist_tools_on_path — which self-gates on that directory and is already
macOS-aware. It still verifies amd64 emulation and still sets up login
autostart, both of which are genuinely needed and neither of which wants admin.
Skipping the admin gate is deliberate, not incidental: Tier 0 is precisely the
case RFC 0001 opened up — a user with NO administrator rights on a machine where
someone else already provisioned the runtime. That user could not install at all
before this.
Every other tier is byte-identical, including an UNSET INSTALL_TIER (a stale
bootstrap that never fetched probe.sh), which keeps the privileged path.
Seven bats tests; the four that matter are mutation-real — removing either the
install_macos branch or the cli-tools target branch fails them. 985 bats green.
Closes#703
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@LukasWodkaLukasWodka self-assigned this Aug 13, 2026
Comment threadscripts/lib/setup-macos.sh Outdated
The Tier 0 path prints "no administrator rights needed", then called
_install_macos_autostart, whose headless branch writes a system LaunchDaemon via
sudo mkdir / sudo tee / sudo launchctl. On a headless Mac (SSH with a TTY) that
prompts for a password — the exact step-b failure Tier 0 exists to remove — and a
Ctrl-C at the prompt leaves the install half-done before cluster create.
_install_macos_autostart now takes an optional "no-sudo" argument. In that mode
the GUI LaunchAgent path is unchanged (it never needed sudo and is the correct
macOS analogue of a user-level autostart), but the headless LaunchDaemon path —
the only branch that needs root — is skipped with instructions on how to enable
reboot autostart later, instead of calling sudo. The Tier 0 caller passes
"no-sudo"; the privileged path is byte-identical and still installs the daemon.
This mirrors Linux, whose Tier 0 already stays out of privileged autostart.
Four new mutation-real bats tests (24 green): headless no-sudo makes zero sudo
calls and writes no daemon; GUI no-sudo still installs the user LaunchAgent; the
Tier 0 caller passes no-sudo; the privileged caller does not. shellcheck clean at
error severity; scripts/manifest.sha256 regenerated (R8).
Bugbot, client#704.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@LukasWodka

Copy link
Copy Markdown
ContributorAuthor

bugbot run

Comment threadscripts/lib/setup-macos.sh
…cker Desktop (Bugbot, client#704)
Headless Tier 0 skips the boot LaunchDaemon rather than prompt for the password
Tier 0 exists to avoid, so TB_MACOS_AUTOSTART stays unset. But _reboot_note's
not-configured branch is the macOS/Windows GUI fallback: it printed 'open Docker
Desktop to bring tracebloc back'. On a headless Mac that names a runtime which
is not what runs here, an action there is no desktop to perform, and it directly
contradicts the 'colima start' hint the skip printed moments earlier.
That footer is the LAST line of a successful install, so it is the advice the
operator actually leaves with.
Set TB_MACOS_HEADLESS_NO_AUTOSTART at the skip site and give _reboot_note a
branch for it. A configured autostart still wins, so a stale marker cannot
downgrade a real promise.
Tests cover both summary branches, that the skip path actually sets the marker
(otherwise the new branch is unreachable and the tests are theatre), and that a
GUI session does not. The existing golden 'open Docker Desktop' assertion is
unchanged. manifest.sha256 regenerated; make check green.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6454d39. Configure here.

Comment threadscripts/lib/setup-macos.sh

@saadqbalsaadqbal 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.

Parity story holds up: macOS Tier 0 now mirrors Linux's — same ~/.local/bin + no-sudo tools target, same "no privileged step" contract, unset INSTALL_TIER still takes the privileged path, and the autostart split (GUI LaunchAgent kept, headless LaunchDaemon skipped) is the right macOS analogue of Linux leaving docker.service enable to the user in Tier 0. Ran the suite on a real Mac: 28/28 green (incl. the 4 footer tests and the no-sudo tests), manifest hashes match the changed libs, shellcheck clean at error severity. The Bugbot footer nit is genuinely fixed — headless Tier 0 names colima, and a configured autostart still wins over the marker. One optional nit inline; not approving (my own PR).

Comment threadscripts/lib/setup-macos.sh Outdated
shujaatTracebloc
shujaatTracebloc previously approved these changes Aug 13, 2026

@shujaatTraceblocshujaatTracebloc 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.

Approving — with a fix pushed to your branch for the live Bugbot finding.

The Tier 0 path itself is right. A Mac with Docker Desktop already installed and answering being sent through _macos_require_admin + preflight_sudo and dying there is a real defect, and skipping the admin gate is the correct response rather than a shortcut: Tier 0 is precisely the case RFC 0001 opened up — a user with no administrator rights on a machine someone else provisioned. Giving macOS the branch Linux has had since #1175 closes a genuine asymmetry.

I confirmed the earlier sudo-prompt finding is properly fixed, not just argued away: _install_macos_autostart really does honour no-sudo, and the headless branch return 1s before any sudo mkdir/tee/launchctl. That thread is outdated now.

The follow-on finding was real, and I traced it rather than trusting the summary:

  1. headless + no-sudo → warn, hint colima start, return 1TB_MACOS_AUTOSTART never set
  2. _reboot_note (summary.sh:107) → OS != Linux, autostart != 1 → falls to the GUI fallback
  3. prints After a reboot, open Docker Desktop to bring tracebloc back. — as the last line of a successful install

On a headless Mac that names a runtime which isn't what runs there, an action there's no desktop to perform, and it contradicts the colima start hint from three lines earlier. The not-configured branch was only ever written for the GUI case; Tier 0 introduced a second way to reach it.

Fixed in the pushed commit by setting TB_MACOS_HEADLESS_NO_AUTOSTART at the skip site and giving _reboot_note a branch for it — a marker rather than having summary.sh re-derive GUI-ness, since _has_gui_session lives in setup-macos.sh and a second copy of that condition is how the two drift.

Four tests, including the one that keeps this honest: that the skip path actually sets the marker. Without it the new summary branch is unreachable in production and the other tests prove nothing. Also pinned that a configured autostart still wins (a stale marker can't downgrade a real promise), that a GUI session doesn't set it, and the existing golden open Docker Desktop assertion is untouched.

setup-macos-lifecycle.bats 28/28 summary.bats 28/28
bats-hygiene.bats 18/18 make check green
CI all green, bats SUCCESS, Bugbot NEUTRAL

manifest.sha256 regenerated — make check's drift gate catches that, but it's the easy one to miss on an installer PR.

LGTM.

…a (Bugbot + @saadqbal, client#704)
My previous commit fixed the footer naming Docker Desktop on a headless box, but
replaced it with an unconditional 'colima start' — the same defect in the other
direction, and inconsistent with the privileged path ten lines below, which
already resolves `command -v colima` and softens to a generic message when it
is absent (#430 Bugbot).
Three cases now:
* boot daemon ALREADY installed — Tier 0 means someone else provisioned the
box, so a prior admin install may have left it. Skipping the write is still
right (we hold no sudo), but claiming manual recovery would be false. Set
TB_MACOS_AUTOSTART and return 0.
* colima resolvable — name 'colima start', as before.
* colima absent — say 'start your Docker runtime manually' and name nothing.
The summary reads the command the skip site resolved against this host rather
than hardcoding one, so the two can't disagree.
Tests for all three, plus the generic summary branch. The no-colima test
overrides `command -v` for colima alone rather than emptying PATH, which would
also remove date(1) via log and test the harness instead of the branch.
31/31 lifecycle, 28/28 summary, hygiene 18/18, make check green, manifest
regenerated.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@shujaatTracebloc

Copy link
Copy Markdown
Contributor

E2E cluster (ubuntu-22.04) is red on an infrastructure flake, not this change — it needs a re-run.

failed to pull image 'rancher/k3s:v1.29.4-k3s1':
Head "https://registry-1.docker.io/v2/rancher/k3s/manifests/v1.29.4-k3s1":
Get "https://auth.docker.io/token?...": net/http: request canceled while
waiting for connection (Client.Timeout exceeded while awaiting headers)

A Docker Hub auth-token timeout during cluster creation. Three independent reasons it cannot be the code:

  • Its siblings passed on the same commitE2E cluster (ubuntu-24.04) and (ubuntu-24.04-arm) are both green off the identical tree. A real regression would not pick one distro.
  • The diff is macOS-only.setup-macos.sh, a setup-macos-lifecycle.bats file, and a summary.sh hunk that lives inside if [[ "$OS" != "Linux" ]] — unreachable on a Linux E2E run.
  • It failed before reaching any installer code, during k3d cluster creation while pulling the k3s image.

Everything else is green: bats (bash unit, mocked): SUCCESS, Cursor Bugbot: SUCCESS (no findings), zero unresolved threads.

I don't have re-run rights on this repo, so this one needs a nudge from you — same as the gate-nudge I flagged on .github#237. My approval stands on the code.

@shujaatTraceblocshujaatTracebloc 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.

Re-approving: my earlier approval was auto-dismissed by the follow-up commit I pushed, so this replaces it on the current head.

The Tier 0 path is right. A Mac with Docker Desktop already installed and answering being sent through _macos_require_admin + preflight_sudo and dying there is a real defect, and skipping the admin gate is principled rather than expedient: Tier 0 is exactly the case RFC 0001 opened up — a user with no administrator rights on a machine someone else provisioned. Giving macOS the branch Linux has had since #1175 closes a real asymmetry. Verified the no-sudo contract holds: the headless branch returns before any sudo mkdir/tee/launchctl, and the tests assert zero recorded sudo calls.

Two rounds of findings, both landing on the reboot footer, both now fixed.

The first: headless Tier 0 skips the boot daemon, so TB_MACOS_AUTOSTART stays unset and _reboot_note fell through to the GUI fallbackopen Docker Desktop, as the last line of a successful install, on a machine with no desktop, contradicting the colima start hint printed moments earlier.

The second was against my own fix, and @saadqbal identified the cleanest statement of it: I replaced that with an unconditional colima start, while the privileged path ten lines below already resolves command -v colima and softens when it is absent (#430 Bugbot). Two paths in one function naming the runtime differently is exactly the mismatch that seeds a support ticket. Bugbot also caught a case I had missed outright — Tier 0 means someone else provisioned the box, so a prior admin install may already have left io.tracebloc.runtime in place, making any "start it yourself" line false.

Final shape:

statebehaviour
boot daemon already installedTB_MACOS_AUTOSTART=1, return 0 — nothing to do, still zero sudo
colima resolvablenames colima start
colima absent"start your Docker runtime manually", names nothing

The summary reads the command the skip site resolved against this host rather than hardcoding one, so the two cannot drift apart.

setup-macos-lifecycle.bats 31/31 summary.bats 28/28
bats-hygiene.bats 18/18 make check green (manifest regenerated)
CI: bats SUCCESS · Cursor Bugbot SUCCESS · 0 unresolved threads

Tests cover all three branches plus both summary outcomes, including the one that keeps it honest — that the skip path actually sets the marker, without which the summary branch is unreachable and the rest prove nothing. The golden open Docker Desktop assertion for the GUI case is untouched.

The single red check, E2E cluster (ubuntu-22.04), is a Docker Hub token timeout pulling rancher/k3s — detailed in a separate comment. Its two sibling distros are green off the identical commit and this diff cannot reach a Linux run. It needs a re-run, which I don't have rights to trigger.

LGTM.

@LukasWodka
LukasWodka merged commit 55b527e into developAug 13, 2026
71 of 72 checks passed
@LukasWodka
LukasWodka deleted the fix/703-macos-tier0-path branch August 13, 2026 15:22
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Installer (macOS): no Tier 0 path — a Mac with Docker already running is still forced through the admin/sudo gate

3 participants

@LukasWodka@shujaatTracebloc@saadqbal