← index2026-05-10 03:21 (Beirut)(backfill from DOCUMENTATION/)

HeyBrian v4 Architecture — as of 2026-05-09

HeyBrian v4 Architecture — as of 2026-05-09

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).

Mission

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.

Topology

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

Components

HeyBrian.app — /Applications/HeyBrian.app/Contents/MacOS/HeyBrian

Source: /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

Source modules (Swift)

Native overlay opt-out

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.

Lua control center — ~/.hammerspoon/brian_controller_ui_v2.lua

Reference 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.

Hetzner-side glue

Caddy — /opt/agent/caddy/Caddyfile

mac.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).

Data files on Mac

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

Deployment

Phase status

See /opt/agent/hey-brian-mac/PLAN_STATUS.md for the live ledger.

Outstanding for v4 phase 1

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.