Authoritative snapshot of the v4 control center as it stands after
Jonah's overnight push. Source files live at /opt/agent/hey-brian-mac
(deployed to /Applications/HeyBrian.app on Mac) and /opt/agent/mac
(Lua reference, ~/.hammerspoon/brian_controller_ui_v2.lua live).
HeyBrian.app on Jonah's Mac is the single host of every Brian-on-Mac
function — UI, cpanel, voice, wake-word, executors. mac.jonahtebaa.com
is the same product viewed remotely. Hammerspoon Lua module retires.
App closed → system down.
Hetzner agent stack (89.167.17.183)
├─→ MacAccessGateway (mac_access_gateway.py) — opens session via /v2 lifecycle
│ │
│ ↓ HMAC over Tailscale
│ │
Mac ┌───────┴────────────┬───────────────────┐
│ │ │
│ HeyBrian.app ←──── /v2/* + /cpanel/* │
│ :9100 (master proxy) │
│ │ │
│ ├─→ native Swift executors │
│ │ (12/12 caps native today) │
│ │ │
│ └─→ proxyToLua (fallback for any │
│ cap with backend=proxy) │
│ │ │
│ Hammerspoon ←────┘ │
│ :8765 (Lua control center │
│ v3, retiring at 1.11) │
│ │ │
│ └─→ DMS: self-shut if HeyBrian │
│ dead 15s (gemini ask, 1.8) │
│ │
└─────────────────────────────────────────┘
Public web (mac.jonahtebaa.com)
└─→ Caddy reverse_proxy → 100.79.172.24:9100
only /cpanel + /cpanel/* + /health
/api/mac/* and /(PWA) still gate-auth-protected
/Applications/HeyBrian.app/Contents/MacOS/HeyBrianSource: /opt/agent/hey-brian-mac/Sources/. Built via ./build.sh
(cross-compiles on Mac via SSH, code-signs with stable Brian Local Dev
cert, deploys atomically).
Listens on TCP :9100 (HTTP/1.1, raw socket). Routes:
| Route | Auth | Purpose |
|---|---|---|
GET /health |
none | liveness probe |
GET /v2/caps |
none | capability registry — public per v3 |
POST /v2 |
HMAC | session lifecycle — calls SessionState.handle |
POST /v2/action |
HMAC | cap dispatch — registry lookup + backend dispatch |
POST /v2/border-test |
none (dev-only) | preview the breathing border for N seconds |
GET /cpanel |
none | bundled HTML (cpanel.html from app Resources) |
GET /cpanel/api/state |
token OR HMAC | live state + audit ring |
POST /cpanel/api/toggle |
token OR HMAC | toggle a cap on/off |
POST /cpanel/api/source-allow |
token OR HMAC | flip allowed-sources |
POST /cpanel/api/stop-session |
token OR HMAC | force-stop active session |
GET /cpanel/api/permissions |
token OR HMAC | TCC probe (read-only) |
POST /cpanel/api/permissions/warmup |
token OR HMAC | actively trigger TCC dialogs |
GET /cpanel/api/audit/verify |
token OR HMAC | walk the audit log hash chain; {intact: true/false, reason?} |
POST /notify, POST /activate, GET /status, POST /ask_screen, POST /start_loop, POST /cancel_loop |
HMAC (post-1.12) | pre-existing v1 routes for proactive pushes / PWA |
~/.brian/nonce_lru.jsonl (mode 0600)~/.brian/cpanel_token) OR HMAC (X-Brian-Sig)~/.brian/capabilities.json mirror, mtime reload, atomic patch preserves unknown JSON fields (codex review fix). Phase 1.12-C: Cap.riskTier (low/medium/high) — metadata today, behavioral hooks pending~/.brian/backend_overrides.json (mode 0600). Per-cap proxy|swift|lua flag; Lua doesn't see this file~/Library/Logs/Brian/control_center.jsonl append-only, 10MB rotate, 100-entry in-memory ring for /cpanel/api/state.recent_audit. Phase 1.12-B: every entry chained via prev_hash + hash (sha256 of canonical JSON). verifyChain() walks the file and returns first broken linkseenBySource, usedByCap, callsByCap, failsByCap. Daily reset at local-TZ midnight/v2 lifecycle state machine. Singleton holds the active session. 60s stale-heartbeat watchdog auto-stops. Drives the three overlays (border / status box / pill).. resolutionhttp://127.0.0.1:9100/cpanel#t=<token>; cpanel JS persists token to localStorage and strips the hash. Menubar entry "Open Settings…" (Cmd-,)Set ~/.heybrian/config.json to {"native_overlays_enabled": false}
+ relaunch HeyBrian. The /v2 lifecycle still updates SessionState
(so /cpanel/api/state.session still shows live), but no overlays
mount. Useful if a regression appears in the wild.
~/.hammerspoon/brian_controller_ui_v2.luaReference at /opt/agent/mac/brian_controller_ui.lua. ~1400 LOC.
Listens on :8765. Used as the proxy fallback for any cap with
backend=proxy. With 12/12 native caps + backend_overrides.json
flipping all 12 to swift, Lua's executor path is inactive.
Phase 1.8 dead-man's switch: every 5s, pgrep for HeyBrian. After 3
consecutive misses (~15s), state.server:stop() and dismount UI.
Closes the "Lua ghosting" hole gemini flagged in the 1.1c round-table.
/opt/agent/scripts/mac_access_gateway.py. Opens a session by sending /v2 start (HMAC) to Mac, polls /v2 heartbeat every 30s during work. PreToolUse hook /root/.claude/hooks/brian-mac-access-gateway-guard.py blocks raw SSH unless via this gateway. Whitelisted helpers: mac_ssh, heybrian_relaunch.sh, hammerspoon_reload.sh./opt/agent/scripts/heybrian_mac_watchdog.py. Cron * * * * *. Probes :9100 + :8765, alerts LOGS after 3 consecutive misses (level=low, never SIP)./opt/agent/scripts/heybrian_contract_test.py + heybrian_contract_corpus.json. Replays envelopes against both backends, diffs responses. Currently 22 cases covering 12 caps. Run anytime./opt/agent/caddy/Caddyfilemac.jonahtebaa.com block proxies /cpanel + /cpanel/* + /health
to 100.79.172.24:9100. forward_auth matcher excludes those paths
so cookie-based gate_auth doesn't intercept the cpanel surface (the
panel uses its own X-Brian-Cpanel-Token).
| Path | Mode | Owner | Purpose |
|---|---|---|---|
~/.brian_mac_secret |
0600 | Jonah | HMAC secret, 32+ hex chars |
~/.brian/cpanel_token |
0600 | Jonah | Cpanel token, 32-hex (128-bit) |
~/.brian/capabilities.json |
0600 | Jonah | Shared registry (Lua + Swift read; Swift writes via /cpanel/api/toggle) |
~/.brian/backend_overrides.json |
0600 | Jonah | Swift-only per-cap routing flag |
~/.brian/nonce_lru.jsonl |
0600 | Jonah | Persisted nonce LRU (phase 1.5) |
~/.brian/no_speech |
0600 | Jonah | Mute flag for say cap |
~/.heybrian/config.json |
0600 | Jonah | Optional native_overlays_enabled kill-switch |
~/Library/Logs/Brian/control_center.jsonl |
— | Jonah | Audit log JSONL, 10MB rotate |
~/Library/Logs/HeyBrian/heybrian.log |
— | Jonah | App log |
cd /opt/agent/hey-brian-mac && ./build.sh — cross-compiles + scp + codesign + atomic deploy. Compile-fail = no deploy = previous app intact. Backups at /tmp/heybrian/backups/ keep N=last few./opt/agent/scripts/heybrian_relaunch.sh (allowlisted in gateway hook for chicken-and-egg recovery)./opt/agent/scripts/hammerspoon_reload.sh.See /opt/agent/hey-brian-mac/PLAN_STATUS.md for the live ledger.
After phase 1: phase 2 absorbs the Mac Access Gateway UI surface from
Hammerspoon (gemini's "single app" path), phase 3 hotkeys + panel/prompt
webviews, phase 4 retires Hammerspoon entirely.