Files
mac/.claude/handoffs/2026-09-15-194209-mac-setup-shipped.md
T
2026-09-15 19:43:11 -04:00

142 lines
7.8 KiB
Markdown

# Handoff: [TASK_TITLE - replace this]
## Session Metadata
- Created: 2026-09-15 19:42:09
- Project: /home/claude/bin/mac
- Branch: master
- Session duration: [estimate how long you worked]
### Recent Commits (for context)
- 617fc78 docs: reconcile CLAUDE.md/DECISIONS with what shipped (sudo approach, rrsync, set -e lessons)
- d622cf6 fix: chmod 600 the ssh Include file (ssh rejects group-writable config)
- d7205a9 fix: pass pubkey to tank-side.sh via env, not ssh command arg
- af51e0c fix: make SparkFun removal and launchd bootstrap non-fatal under set -e
- 39f61f4 fix: unattended sudo via temporary NOPASSWD drop-in with triple cleanup
## Handoff Chain
- **Continues from**: None (fresh start)
- **Supersedes**: None
> This is the first handoff for this task.
## Current State Summary
Bootstrapped `~/bin/mac` from scratch: scaffolded the project, SSH'd into Seth's new MacBook Pro (M1 Pro, 32GB, macOS 26.2 Tahoe), brainstormed + specced + planned a debloat/Linux-feel/Ableton-first setup, then implemented and RAN it end-to-end. `scripts/run.sh` applied cleanly (exit 0, idempotent on re-run), and the tank backup path is proven working with rrsync jailing + sanoid history. Remaining work is entirely Seth's GUI-only manual checklist and installing Ableton Live — no more code needed to ship the base setup.
## Codebase Understanding
### Architecture Overview
Managed over SSH from steel141: `scripts/run.sh` rsyncs the repo to `~/mac` on the Mac, installs a TEMPORARY NOPASSWD sudoers drop-in (so Homebrew's long, child-spawning install has sudo), runs `scripts/setup.sh` there, removes the drop-in, pulls `defaults` backups to `.backup/mac/`. `setup.sh` is idempotent: each section prints `[skip]` or `[set]`. Config files (bashrc, kitty.conf, ssh_homelab) live in `config/` and are *included* by marker lines in the real dotfiles, so editing the repo edits the machine. Backup = launchd nightly rsync of `~/Music/Ableton`+`~/Documents` to `pve173:/tank/backups/mac`, key rrsync-jailed, sanoid `tank_media` template for history.
### Critical Files
| File | Purpose | Relevance |
|------|---------|-----------|
| `scripts/run.sh` | steel141 entry point (rsync+sudo drop-in+setup+cleanup) | run as `scripts/run.sh [--no-tank]`; needs `$HOMELAB_PASSWORD` |
| `scripts/setup.sh` | on-Mac idempotent configurator | 2nd run = all `[skip]` |
| `scripts/_install_sudoers.sh` | installs temp NOPASSWD drop-in (validated) | password piped to stdin |
| `scripts/backup.sh` | nightly rsync to tank | `/opt/homebrew/bin/rsync`, rrsync remote |
| `scripts/tank-side.sh` | pve173: dataset+sanoid+rrsync key | PUB via env, not arg |
| `docs/manual-checklist.md` | GUI-only Tahoe steps for Seth | the remaining work |
| `docs/reference/inventory-2026-09-15.md` | pre-change baseline | "was X stock?" |
### Key Patterns Discovered
- `set -euo pipefail` everywhere; optional/cosmetic steps MUST be `|| warn` or they abort the run (learned the hard way — SparkFun + launchctl bootstrap).
- SSH runs on macOS are NON-login: `source ~/.bash_profile` before expecting GNU PATH.
- ssh Include files must be `chmod 600` (rsync -a brings over group-writable 664, which ssh rejects).
- Passing args through `ssh host 'cmd' -- "$X"` re-splits on spaces remotely; pass via env instead.
- `defaults`/`pmset` backed up to `~/.mac-setup-backup/` before writes; pulled to `.backup/mac/`.
## Work Completed
### Tasks Finished
- [x] Project scaffolded, repo `git.sethpc.xyz/Seth/mac`, `ssh mac` alias
- [x] Inventory captured (pre-change)
- [x] Design spec + implementation plan written
- [x] Brewfile, setup.sh, run.sh, backup.sh, tank-side.sh, checklist written
- [x] `run.sh` applied on the Mac (exit 0), verified idempotent
- [x] Linux feel verified: bash 5.3.20, GNU sed, `ip`, hostname `mac`, tools in /opt/homebrew
- [x] DAW power profile, Dock=2 apps, defaults all applied
- [x] Tank backup proven: rrsync restriction enforced, upload + `--delete` + sanoid snapshots working
### Files Modified
| File | Changes | Rationale |
|------|---------|-----------|
| [no modified files detected] | | |
### Decisions Made
| Decision | Options Considered | Rationale |
|----------|-------------------|-----------|
| Temp NOPASSWD sudoers over pty password injection | Seth chose it; pty inject raced & hung 14 min | see DECISIONS.md |
| rrsync-jailed backup key | laptop key must not be unrestricted root on tank | enforced & proven |
| bash5 / no Cmd-swap / Rectangle / rsync-not-TimeMachine | Linux feel + DAW safety | DECISIONS.md |
## Pending Work
### Immediate Next Steps
1. Hand Seth `docs/manual-checklist.md` — the GUI-only steps (iCloud Drive Desktop&Documents OFF, DAW Focus, app first-launch grants for Rectangle/kitty/Tailscale, Screen Time/Handoff off).
2. Install Ableton Live 12 from ableton.com, then re-run `scripts/run.sh --no-tank` so the Dock picks up Live (setup.sh only adds it if `/Applications/Ableton Live 12*.app` exists).
3. Once an audio interface is attached: set it in Live > Settings > Audio (48kHz/128 buffer), verify no sleep/notifications during a 15-min AC session with DAW Focus on. Also unresolved: Traktor S4 MK1 macOS support (NI dropped it years ago) — verify before assuming it works as a Live controller.
### Blockers/Open Questions
- [ ] None blocking. Open: S4 MK1 macOS controller support unverified; audio interface not yet chosen/attached.
- [ ] FileVault is ON — after any reboot, `ssh mac` is dead until someone types the password at the lid.
### Deferred Items
- SparkFun PPP service left (macOS refuses removal of sole service on a port; harmless).
- Tailscale not yet logged in (GUI). AeroSpace tiling deferred (Rectangle chosen).
- Suite/third-party sample packs: in-app + SMB copy from Milkie, on the checklist.
## Context for Resuming Agent
### Important Context
The base setup is DONE and verified — do NOT re-run destructively or reconfigure. `scripts/run.sh` is idempotent and safe to re-run (it re-installs/removes the temp sudoers drop-in each time). Everything left is Seth's GUI checklist + Ableton install. If `ssh mac` fails, first suspect a reboot (FileVault locks SSH until password entry at the lid), not a config problem. Never leave `/etc/sudoers.d/mac-setup` behind — run.sh removes it three ways, but if a run is force-killed mid-way, verify with `ssh mac 'test -e /etc/sudoers.d/mac-setup && echo BAD || echo ok'`.
### Assumptions Made
- Seth is physically at the Mac (enabled Remote Login mid-session).
- `$HOMELAB_PASSWORD` is the Mac's login/sudo password (verified — it worked).
- The Mac stays on AC while producing (power profile only changes AC, not battery).
### Potential Gotchas
- `pkill -f 'ssh ... mac'` will kill your OWN session (matched my command line once — cost a retry).
- SSH is non-login: GNU tools/PATH need `source ~/.bash_profile`.
- A fast test passing does NOT mean it's reliable — the pty password inject passed a 20s test then hung 14 min live.
## Environment State
### Tools/Services Used
- `ssh mac` (192.168.0.94, key auth), `ssh pve173` (tank host). Homebrew at /opt/homebrew.
- backup launchd: `~/Library/LaunchAgents/xyz.sethpc.mac-backup.plist` (03:30 nightly).
### Active Processes
- Backup launchd agent loaded (idle until 03:30). sanoid.timer active on pve173.
- No leftover background jobs from this session (drop-in removed, self-destruct sleepers killed).
### Environment Variables
- `HOMELAB_PASSWORD` (in claude's env on steel141; used by run.sh and cleanup).
## Related Resources
- `docs/plans/2026-09-15-mac-setup-design.md` (spec), `docs/plans/2026-09-15-mac-setup-plan.md` (plan)
- `docs/manual-checklist.md` (remaining work), `docs/reference/inventory-2026-09-15.md` (baseline)
- `DECISIONS.md` (why), `~/bin/ableton/` (Wine attempt archive, sibling project)
---
**Security Reminder**: Before finalizing, run `validate_handoff.py` to check for accidental secret exposure.