Architecture pivot 2026-05-09 (later afternoon, Jonah): v4 — HeyBrian app becomes the host of everything. User installs HeyBrian, gets the whole system. App closed → everything down. mac.jonahtebaa.com is the same product viewed remotely.
Source-of-truth design:02_v4_heybrian_consolidated.md(codex round-table integrated).01_control_center_architecture.mdkeeps the wire protocol (HMAC, /v2/action, capability registry) that v4 inherits.
Status keys: DONE | IN PROGRESS | TO DO
hs.httpserver:8765, HMAC-verified /v2, /v2/action (12 executors), /v2/caps, /cpanel, capability registry at ~/.brian/capabilities.json, audit log + size rotation, in-memory metrics, breathing 4-layer cyan border, clickable pause/stop pill, translucent status box, Glass/Submarine chimes, heartbeat watchdog/v2/action. _raw_ssh tripwire raises if anyone touches it.44a66ea)Per codex: ship JUST the HeyBrian-hosted HTTP control plane + audit/security parity. Defer visual rewrite + remote PWA polish until executor parity is proven.
/v2/caps GET in HTTPServer.swift. HeyBrian binds :9100 (HS keeps :8765). Hetzner gateway gets a MAC_CONTROL_PORT env knob; flip to 9100 for shadow testing. — TO DOrun, click, screencap, type, keystroke, chrome.eval, chrome.url, file.read, file.write, applescript, notify, say). — TO DO/cpanel, /cpanel/api/state|toggle|source-allow|stop-session) in Swift. Same HTML I built, served from app bundle. — TO DOhttp://127.0.0.1:9100/cpanel with token via WKURLSchemeHandler + WKUserScript injection (per codex — no URL params/fragments). — TO DOhttps://mac.jonahtebaa.com/cpanel (Jonah requirement — no separate phone UI). The HTML detects its origin: localhost → token auth direct to HeyBrian; remote → Caddy gate auth, calls go through Hetzner mac_control_routes.py which proxies HMAC-signed to HeyBrian over Tailscale. One HTML file, two delivery paths, same state. — TO DOcapabilities.json to Application Support with one-version compat reads from ~/.brian/. — TO DObrian_controller_ui_v2.lua, HeyBrian rebinds :8765, retire Lua module. Keep dual-port for a week. — TO DOapp-closed = visual-system-down becomes truemac_control_routes.py proxies /api/mac/cpanel/* to HeyBrian over TailscaleGoal: turn the existing UI module into a true control center. Every Mac action enters through one HTTP endpoint, the router renders the UI around it, and a JSON registry decides whether it's allowed.
POST /v2/action {action, params, source, session_id} — TO DO~/.brian/capabilities.json — TO DO~/Library/Logs/Brian/control_center.jsonl — TO DOrun (local shell via hs.task) — replaces remote SSH for in-Mac workclick (cliclick → eventtap fallback)screencap (screencapture)type (cliclick t: → eventtap fallback)chrome.eval (AppleScript execute javascript — the LinkedIn-API trick)~/.brian/secrets/<client>.key)/cpanel)hs.httpserver — TO DOcontrol_center.jsonl) — TO DOmac_access_gateway.py drops _raw_ssh and routes through /v2/action for every operation — TO DObrian-mac-controller daemon — n/a (orchestration moved to Mac)mac_gatekeeper ProxyCommand — n/a (no SSH path to gate anymore)TTSManager.speak routes through /v2/action {action: "say"} — TO DO (gives mute flag + audit + UI for free)/notify calls the same endpoint — TO DO/v2/action — TO DOmac_helper_client.py queue → /v2/action calls — TO DO/opt/agent/data/archives/mac_legacy_v1.tar.gz — TO DOgit rm mac-bin/ssh, mac_ssh_guard.sh, brian_mac_active.sh, brian_mac_status.sh, queue parts of mac_helper_client.py — TO DOcapabilities/<name>.md — TO DOToday's mess: a half-dozen scripts can paint the Mac and trigger TTS. Each is its own painter. The breathing-border rule has to be applied (or accidentally bypassed) at every one.
After v3: one painter, one auth, one toggle panel, one audit log. The breathing-border rule is in the control center's dispatch path — apply it once, it covers everything forever. HeyBrian, voice, Hetzner, and the CLI all become callers, not painters. Jonah can flip any capability on/off from the cpanel without redeploys.