Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
7.5 KiB
Mac setup design — 2026-09-15
Design for turning the stock MacBook Pro (16" 2021 M1 Pro, macOS 26.2 Tahoe)
into a quiet, Linux-feeling, Ableton-first machine, managed over SSH from
steel141. Inventory baseline: ../reference/inventory-2026-09-15.md.
Goals (priority order)
- Ableton Live 12 runs clean: no sleep/App Nap/notifications mid-session, project files never touched by cloud sync, backed up to tank.
- Feels like Linux to a bash user: GNU userland unprefixed,
ip aworks, kitty, bash 5, fast key repeat, no press-and-hold accents, window snapping. - Stock macOS noise off: Dock stripped, Spotlight web/Siri suggestions off, Photos analysis / Game Center / Handoff / iPhone Mirroring / Screen Time off.
- Homelab reachable: tank over SMB, ssh aliases, Gitea, Tailscale.
Non-goals
- Disabling SIP, Gatekeeper, or FileVault. All stay on.
- Removing anything under
/System/Applications(sealed volume). Hide from Dock only. - Swapping Cmd<->Ctrl globally. Live's shortcuts are Cmd-native on Mac.
- yabai (needs partial SIP disable). Tiling is AeroSpace if wanted later; Rectangle now.
- Running samples/projects off the SMB share. Local disk only; SMB is a source to copy from.
- Time Machine (over SMB it's fragile and backs up the whole disk; rsync of the folders that matter is simpler and Linux-familiar).
Decisions taken in this design (defaults — override in DECISIONS.md)
| Fork | Choice | Why |
|---|---|---|
| Login shell | Homebrew bash 5, set via chsh after adding to /etc/shells |
Seth's steel141 shell is bash; macOS ships bash 3.2. zsh stays installed. |
| Cmd/Ctrl | Untouched | Live + every Mac tutorial assume Cmd. kitty handles Ctrl+Shift+C/V itself. |
| Window snapping | Rectangle (Homebrew cask) | Zero-config snapping. Upgrade path: AeroSpace if tiling turns out to matter. |
| Backup | launchd user agent -> rsync -a --delete of ~/Music/Ableton and ~/Documents to pve173:/tank/backups/mac/ nightly over SSH |
Transparent, one file, restorable with plain rsync. Needs a Mac->pve173 SSH key. |
| Hostname | PARAMETER — not yet chosen | Seth names machines (bebop, yoga, steel141). setup.sh takes it as HOSTNAME=. |
| iCloud | Account stays (Find My, Keychain). iCloud Drive "Desktop & Documents" sync OFF | Sync mid-save corrupts/evicts DAW project files. GUI-only toggle -> manual checklist. |
| Spotlight | Indexing stays ON; Siri Suggestions + web results OFF | Finder search still useful; Live's browser has its own index. |
Components
All live in ~/bin/mac/. Pushed to git.sethpc.xyz/Seth/mac. Applied by
ssh mac from steel141 (seth is the console user, so defaults write +
killall Dock/Finder/SystemUIServer take effect from an SSH session).
Brewfile
Single manifest, applied with brew bundle --file=Brewfile. Contents:
- Formulae:
bash coreutils findutils gnu-sed grep gawk gnu-tar iproute2mac tmux htop ripgrep fd jq wget rsync git tree - Casks:
kitty rectangle tailscale - NOT in Brewfile: Ableton Live (licensed download from ableton.com, manual).
scripts/setup.sh
Idempotent bash, set -euo pipefail, run on the Mac as seth. Sections, in order:
- preflight — refuse if not arm64 macOS 26.x; require
HOSTNAMEenv var;xcode-select --installif CLT missing (blocks on a GUI prompt the first time — documented). - backup — for each
defaultsdomain about to be written,defaults export <domain> ~/.mac-setup-backup/<domain>-<epoch>.plist(skip if domain absent). Alsopmset -g customandlaunchctl print gui/$UIDto the same dir. This dir is rsync'd back to~/bin/mac/.backup/by the runner on steel141. - brew — install Homebrew if missing;
brew bundle; write shellenv + gnubin PATH block into~/.bash_profile(guarded by marker comments so re-runs don't duplicate). - shell — add
/opt/homebrew/bin/bashto/etc/shellsif absent;chsh -sif current shell differs. - hostname —
scutil --set ComputerName/LocalHostName/HostName $HOSTNAME. - defaults (Linux feel) — key repeat
KeyRepeat=2 InitialKeyRepeat=15;ApplePressAndHoldEnabled=false; natural scrolling off; Finder: path bar, status bar, all extensions,~as new-window target, list view, no.DS_Storeon network/USB volumes; no window animations (NSAutomaticWindowAnimationsEnabled=false); hot corners cleared. - defaults (debloat) — Dock: autohide, no recents,
persistent-appsrewritten to Finder/kitty/Live/System Settings (Live entry only if/Applications/Ableton Live 12*.appexists); Spotlight Siri suggestions off; Game Center + Handoff (NSUserActivityTrackingEnabled) + Screen Time related agents disabled withlaunchctl disable gui/$UID/<label>only after the label is confirmed present on this OS. Remove the "SparkFun Pro Micro" PPP network service (networksetup -removenetworkservice). - power (DAW) —
sudo pmset -c sleep 0 displaysleep 0 disksleep 0 powernap 0; battery profile untouched. App Nap off for Live viadefaults write com.ableton.live NSAppSleepDisabled -bool true. - homelab —
~/.ssh/configseeded with the steel141 aliases (pve*, bebop, etc.); tank SMB mount instructions written (mount itself is GUI /mount_smbfsat login — see checklist); Tailscale cask installed, login is GUI. - backup agent — install
~/Library/LaunchAgents/xyz.sethpc.mac-backup.plist(StartCalendarInterval 03:30) runningscripts/backup.sh(the rsync). - apply —
killall Dock Finder SystemUIServer.
Each section prints [skip] when already in desired state. No section
prompts except the CLT install and sudo for pmset/chsh/hostname.
scripts/backup.sh
rsync -a --delete -e ssh ~/Music/Ableton ~/Documents root@192.168.0.173:/tank/backups/mac/.
Logs to ~/Library/Logs/mac-backup.log. Uses claude-style key
~/.ssh/id_ed25519 generated on the Mac and installed on pve173 (manual step,
one-time).
docs/manual-checklist.md
GUI-only steps on Tahoe, in order, each with the exact Settings path:
iCloud Drive Desktop&Documents off; Photos analysis off; Screen Time off;
iPhone Mirroring off; Focus mode "DAW" (all notifications silenced, shown in
Control Center); Rectangle accessibility grant; kitty full-disk-access grant
(for ~/Music/Ableton under TCC); Tailscale login; Live install + Suite Packs
download; audio interface buffer/sample rate in Live once one is attached.
Verification
setup.shrun twice in a row: second run is all[skip]lines, exit 0.ip a,ls --color,sed --version(GNU),echo $BASH_VERSION-> 5.x,hostname-> chosen name — all overssh mac.pmset -g customshows ACsleep 0 powernap 0, battery unchanged.defaults read com.apple.dock persistent-appsshows only the 4 entries.backup.shdry-run (-n) lists files; real run creates/tank/backups/mac/Abletonon pve173.- Live: open a project, leave it 15 min on AC, confirm no sleep and no notifications appear (Focus on).
Rollback
Every defaults domain has a pre-write plist in .backup/; restore with
defaults import <domain> <file> + killall Dock Finder. pmset -g custom
snapshot restores with the same flags. chsh -s /bin/zsh reverts shell.
brew bundle cleanup / brew uninstall for packages. Nothing in this design
is irreversible.
Order of operations
- Seth picks hostname ->
DECISIONS.md. - Write
Brewfile,setup.sh,backup.sh,manual-checklist.md. - Run
setup.shover SSH (CLT prompt needs Seth at the lid once). - Seth walks
manual-checklist.md. - Install Live, attach interface, verify.
- Handoff.