c62aa7b805
prd-number-check / require-numbered-prds (pull_request) Successful in 10s
tracker-policy-pr / check-pr (pull_request) Successful in 13s
test / image-input-builds (pull_request) Successful in 43s
test / unit (pull_request) Successful in 51s
test / integration-docker (pull_request) Successful in 59s
test / coverage (pull_request) Successful in 15s
lint / lint (push) Failing after 14m25s
The macOS install harness caught this on its first real run: a throwaway account gets `bot-bottle install: error: python3 3.11 or newer is required` and stops. A fresh account's PATH is just /etc/paths, which excludes /opt/homebrew/bin, so `python3` resolves to the Command Line Tools stub — still 3.9.6 on macOS 26. Homebrew's shellenv line lives in the *installing* user's ~/.zprofile and is inherited by nobody. The documented `curl … | sh` path therefore dead-ends for anyone whose profile isn't already set up, which is every new user, launchd job, and CI runner. So look past PATH before giving up: try `python3`, then python3.11-3.14, then /opt/homebrew/bin, /usr/local/bin, ~/.local/bin, and python.org framework builds, and say which one was picked when it isn't the obvious one. On this host that turns the failure into a successful install. The chosen interpreter is now threaded through everything downstream — the pip probe, the PEP 668 check, the pip --user fallback, and the user-scripts-dir lookup — which were all still hardcoding `python3` and would otherwise have run against the 3.9 stub we just rejected. `pipx install` gains `--python`, since pipx otherwise builds the venv with whichever interpreter pipx itself was installed with, not the one that passed the version check. When nothing usable is found the error is now actionable: what was found and why it's insufficient, where else it looked, a platform-appropriate install command, and BOT_BOTTLE_PYTHON to point at an interpreter directly. An explicit BOT_BOTTLE_PYTHON that is too old or unusable is an error rather than a silent fallback to a different interpreter than the caller asked for. Three existing tests asserted on incidental literals rather than the behaviour they describe, and are narrowed to their actual intent: * `never_uses_sudo` matched the word anywhere, including the new "sudo apt install python3.12" remediation *advice*. It now strips string literals and comments first, so it still catches sudo as a bare command, in a pipeline, and in a command substitution — verified by mutation — while allowing the script to print the word. * `checks_pip_usable_before_fallback` pinned the literal `python3 -m pip`. * `resolves_user_scripts_dir_not_hardcoded` banned ".local/bin" script-wide; it's now scoped to the USER_SCRIPTS assignment it exists to guard, since ~/.local/bin is a legitimate place to *find an interpreter*. README grows the install command and a Requirements section it never had, leading with the Python floor and why a working `python3` in your own shell says nothing about what a fresh account sees. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WEfZZhakx13bxTfXcZCoS5