ci / rust (push) Failing after 2m11s
Cross-host (T2-brokered) attach fails when no shared perimeter is configured: the daemon rejects the upgrade with a structured 502 (no_perimeter_candidate / no_local_perimeter / perimeter_mismatch / peer_unreachable), but maestro-web's WS proxy had already upgraded the browser socket and merely dropped it on the upstream failure — the attach pane flashed and vanished with no reason shown. - maestro-web proxy: on a failed upstream handshake, relay the daemon's error message to the browser as an application close frame (4502 + reason) instead of a bare drop; parse the structured JSON error body. - web attach.ts: on a 4000+ close with a reason, show it in the pane header and terminal body and keep the pane up, rather than auto-closing. - daemon: WARN at startup when no perimeter_id/private_addr is configured, since cross-host attach is then unavailable. - docs/INSTALL.md: document the required matching perimeter_id + per-host private_addr for cross-host attach. Closes #39 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>