diff --git a/docs/research/testing-clean-install-on-macos.md b/docs/research/testing-clean-install-on-macos.md index 2bd36e33..1f101a59 100644 --- a/docs/research/testing-clean-install-on-macos.md +++ b/docs/research/testing-clean-install-on-macos.md @@ -237,10 +237,35 @@ service is per-user. It asserts the install is sound and *reports* backend readiness without failing on it, because install.sh provides no backend and so cannot regress one. -`test-ready` models a system **with** them: it runs `container system start` -for the throwaway user, then demands doctor go fully green, backend included. -(`bot-bottle backend setup --backend=macos-container` does not start the -service — it only checks and tells you to run that command yourself.) +`test-ready` models a system **with** them, then demands doctor go fully green, +backend included. Both variants pass as of this writing. + +### The per-user prerequisite is two steps, not one + +Running it revealed that "set up the backend for this account" is more than +starting a service: + +1. **`container system start`** — the service is per-user. The run confirms it + directly: the throwaway account's `appRoot` is + `/Users/bbtest/Library/Application Support/com.apple.container/`, its own, + and starting it left the admin's service untouched. +2. **A guest kernel**, which also lives in that per-user app root. A fresh + account has none, so `container system start` prompts to download one — + and *only* prompts, since the flags default to asking. Headless callers + must pass `--enable-kernel-install` or the command dies on + `failed to read user input`. + +Neither step is done by `bot-bottle backend setup --backend=macos-container`, +which only checks and then tells you to run `container system start` yourself. +So a new account's real path to a working backend is: +`container system start --enable-kernel-install`. + +The harness must also enter the user's launchd domain via +`launchctl asuser ` to do any of this. `container system start` registers +`com.apple.container.apiserver` as a per-user launchd agent and talks to it +over XPC; from plain `sudo -u` the caller is still in root's bootstrap +namespace, the lookup crosses domains, and the apiserver answers +`invalidState: "unauthorized request"` even though the agent started fine. It refuses to start against an existing account (a reused home is not a clean install), and it tears the account down from an `EXIT`/`INT` trap armed the