2026-06-02

BusyBro got sharper: per-user context-aware, role-scoped, links-by-default, and aware of the exact view-state you're looking at. It also grew up on Telegram — account linking via /login, capability-gated WRITE actions, and an inspect_requests tool that reverse-engineers captured auth into runnable repro code. Live service stats and infra status became reachable through MCP, REST, and WS. And a full-codebase security sweep closed a CRITICAL ACL drift plus a stack of HIGH findings. Dashboard builds 284 → 292; Supabase migrations 202 → 214; iOS build 166; proxy-server builds 134 → 136; status build 2; docs builds 153 → 154.

What changed

BusyBro polish (dashboard 284 → 292 / supabase 202 → 205)

  • Role-scoped — the dashboard ask runs BusyBro's read tools through the caller's own RLS, so what it can see is governed by the user's role, and it is told the user's role (203).
  • Links by default — linking the dashboard sections it names is now mandatory on the web surface, rendered as in-app router navigation; code blocks are syntax-highlighted (PrismLight + oneDark) with a language label (203).
  • Exact view-state context — BusyBro knows the precise view you are on (288 / supabase 205), is per-user context-aware with tappable Telegram suggestions (287 / supabase 204), and offers richer empty-state prompts (8 feature- and usage-based starters, 286).
  • UI: the Clear button no longer overlaps the Close ✕ (285).

BusyBro on Telegram (supabase 206 → 211 / dashboard 289)

  • /login account linking — a one-time code links a Telegram user to a dashboard account (consumed under the user's session in a new /account Telegram tab), giving linked askers name- and role-aware answers and a working "who am I". The bot's HS256 user-JWT minting was removed entirely — one auth path, no broken links.
  • /me and /logout/me prints your Telegram identity + linked account (deterministic, no LLM call); /logout unlinks the row; /login now guards against a double-link.
  • Capability-gated WRITE actions — BusyBro can perform role-aware writes with no confirm step, governed by the linked account's capabilities.
  • inspect_requests — a read tool surfacing full captured request/response detail (method, URL, headers, bodies; size-capped, CONNECT rows excluded) for a host, so BusyBro can explain how a real app authenticates from its actual traffic and emit runnable curl/fetch repro snippets with secrets as placeholders. Backed by a fast exact-host index.
  • A streaming reimplementation (SSE + cancel + retry), a "typing…" indicator while BusyBro thinks, and Telegram HTML escaping round it out. The bot command menu (setMyCommands) is now the source of truth, kept in sync with /help and the handlers.

Stats & status via MCP / REST / WS (supabase 212 / dashboard 291 / status 2 / docs 154)

  • Live service stats and infra status are now exposed on api.busymate.net through all three programmatic surfaces. New service_status + service_stats tables (RLS stats:view / status:view, Realtime), a get_stats() RPC, a 60s snapshot cron, and a secret-gated status-ingest Edge Function the VPS pushes to.
  • MCP gained 6 tools — get_stats, get_status, link_telegram, unlink_telegram, get_telegram_link, inspect_requests — bringing the count to 73, with MCP parity for Telegram linking and inspect_requests. The /mcp, /rest, and /ws explorers list the new surface, and stats and status are capability sections in Roles.

iOS (ios 166)

  • Live Activity lock-screen and Dynamic Island polish (build 166).

Security sweep

  • Issue #001 — proxy port exposure — a security specialist was stood up (charter, threat model, issue register) and the fail2ban filter was widened to also ban the whitelist-rejected :8888 probe path.
  • Issue #003 — log rotation + headroomcopytruncate rotation for the ~70GB unrotated proxy log (zero downtime), a device-safe fail2ban jail (the jail had never actually been installed), and pg-streamer buffer/batch headroom (~5x drain throughput) so legit high-volume capture stops dropping on overflow.
  • Issue #009 — presence transport — per-device-presence spun up a supabase-js client without the ws Realtime transport, so on Node 20 every spin-up threw "no native WebSocket support" and retried forever (618k+ failure lines/day). It now passes the WebSocket transport. proxy-server 136 deployed and verified.
  • Audit findings (supabase 213 → 214 / proxy-server 135) — a full-codebase + VPS + advisors audit closed: a CRITICAL SECDEF ACL drift (set_snapshot_schedule + set_live_activity_push_config had reset to anon-callable → cloud-metadata SSRF + APNs-key exfil; grants revoked, advisors 44 → 24); proxy-control RBAC (Realtime writes now require has_capability('devices','edit'), so a viewer can no longer drive resend/breakpoint/restart); MCP RBAC (per-tool capability enforcement across all 73 tools, deny-by-default — previously any OAuth token acted as admin); and a resend SSRF guard in proxy-server blocking resend fetch() to loopback / RFC1918 / link-local / ULA / metadata with connection-pinning against DNS rebind.

Where it's documented