2026-06-01

A server-side project assistant that started life as the Telegram /ask command grew a personality ("Buzz"), got renamed "BusyBro", and moved into the dashboard top bar across every view — persistent, resizable, and able to link the sections it mentions. The iOS Live Activity learned to carry a per-device message you can set from the dashboard, REST, or MCP. Dashboard builds 280 → 283; Supabase migrations 193 → 202; iOS build 165.

What changed

BusyBro — the in-product assistant (supabase 193 → 201 / dashboard 280 → 283)

  • It began as the Telegram /ask command (supabase 193): a server-side, project-aware assistant in the telegram-bot Edge Function.
  • It became agentic with read-only live-data tools (194), then grew a character — concise, human-friendly "Buzz" (195) — and a memory: a friend who knows you, with reply-to-continue threading (196).
  • Ask Buzz in the dashboard (280): a top-bar button available from every view, sharing the same _shared brain as the Telegram path.
  • Renamed Buzz → "BusyBro" everywhere user-visible (281); the chat now persists across reloads and navigation (282).
  • BusyBro answers are navigable: it links the dashboard sections it mentions to their routes (web → in-app router nav that closes the dialog; Telegram → absolute dash.busymate.net URLs), driven by a section→route map. The Ask dialog also became a resizable, persistent modal with a drag handle, size saved to localStorage (283).

Live Activity message (ios 165 / supabase 197 / dashboard 279 / docs 153)

  • A new device_live_activity_message table plus RLS lets you set a per-device message that surfaces on the iOS Live Activity. A foreground broadcast trigger and a background pg_net → push-notify trigger (APNs liveactivity) fan a single row write out to the device.
  • iOS merges the message into every Live Activity state build (it survives VPN toggles) and fetches it on bootstrap/resync; the lock screen and Dynamic Island were redesigned around it (status dot + type badge + full-width message). iOS build 165 was accepted to TestFlight.
  • Dashboard control lives in the device iOS App tab; MCP gained set_live_activity_message (tool count → 67).

MCP OAuth resource check (supabase 198 → 199)

  • The MCP OAuth resource check (RFC 8707) now normalizes the trailing slash and checks by origin, fixing an invalid_target rejection for otherwise-valid clients.

Security — entries-flood vectors closed (supabase)

  • entries was dropped from the MCP writable tables (a generic db_insert/update/delete on it ran with the service-role client, bypassing RLS) — entry mutations stay on the dedicated tag/untag/wipe tools.
  • The e2e admin client now hard-refuses a prod Supabase URL unless explicitly allowed, the reserved-namespace ingest block was generalized to all-zero and all-one device UUIDs (and device-pair refuses to mint them), and a per-device rate limit trigger caps entries at 18 000 rows/min/device.

Where it's documented