06 / CHANGELOG

What changed and when.

Every shipped change with a date and a category. Breaking changes get a callout at the top of the entry, never buried.

Feature Fix Breaking Polish

Android joins iPhone: the same session code, the same technician browser, the same diagnostics.

PlatformAnchorGrid is no longer iOS-only.
The Android app publishes the customer screen over the same connection path as iOS, at 30 fps with hardware H.264, and reuses the technician browser, the one-time code flow, both reconnection tiers, and the diagnostics pipeline. Android is in signed tester builds; iPhone remains the App Store release.
  • Feature
    Android screen sharing
    The customer opens AnchorGrid on Android, shares a one-time code, and approves the capture dialog. The technician watches from the same browser tab they already use for iPhone, with nothing to install on their side.
    Signed tester build
  • Feature
    Automatic recovery on Android
    The same two tiers as iOS: a quick path repair first, a full connection rebuild if that does not take, and the same 90-second give-up cap the browser already enforces. Wi-Fi to cellular handoffs recover without ending the session.
  • Feature
    Diagnostics for Android sessions
    Android sessions upload their timeline, so the Session Story, Health Score, Root Cause, and evidence timeline all work for Android. Timelines are grouped into real phases, including a dedicated Streaming phase.
  • Feature
    Rotation mid-session
    Turning the phone sideways while sharing now resizes the capture. Previously the rotated screen was letterboxed into the original shape, so the technician saw the screen shrink into a band with black down both sides.
  • Fix
    Reopening the app tells the truth
    Leaving AnchorGrid with the home button and reopening it showed the welcome screen while the screen was still being shared, and took away the customer’s only stop control. Session state is now process-scoped, so reopening finds the live session and its End button.
  • Fix
    Smooth video on real hardware
    On a physical phone the hardware encoder was being torn down and rebuilt about thirty times a second whenever the screen moved, so motion looked like a slideshow while a still screen looked fine. Fixed, alongside explicit H.264 selection matching iOS and a frame pacer that ticks on a fixed grid.
  • Fix
    Signed release builds connect
    The signed Android build launched cleanly and then died in a native crash the moment a session started its connection. Fixed for the first tester release.
  • Polish
    Android app design
    The Android app ships the AnchorGrid interface end to end, with Inter and JetBrains Mono standing in for the iOS system typefaces.
  • Polish
    Workspace typography loads
    The technician workspace referenced a web font that never actually loaded in production. It is now self-hosted and renders as designed.

The viewer and the health score stop reporting things that did not happen.

  • Fix
    A render stall no longer ends a healthy session
    A brief stall in the browser’s video rendering could end a session that was still connected and streaming. Stalls are now surfaced as their own state, measured from the decoder rather than the video element, and no longer erase the evidence that explains them.
  • Fix
    The health score stops claiming recoveries that never happened
    Sessions that never actually recovered were being credited with a recovery, which made the score read better than the session went.
  • Fix
    Packet loss is a real percentage
    The loss figure was calculated without a received-packet count in its denominator.
  • Fix
    Giving up actually ends the session
    When the 90-second reconnection cap fired, the viewer reported that it had given up but left the session open behind the message.
  • Fix
    Timeline search matches whole words
    Filtering the evidence timeline matched keywords inside unrelated words, so searches returned entries that had nothing to do with the term.
  • Feature
    Failed joins are audited
    A wrong, expired, or already-claimed session code now writes an audit row recording the reason. Previously a failed join left no trace at all, so someone spraying codes to find a live session looked identical to silence.
  • Fix
    Invitation expiry says 7 days everywhere
    Admin › People claimed invitations lasted 14 days while the invite dialog said 7. The server’s value is 7, so an admin planning around the panel was wrong by half on a security-relevant lifetime.

Multi-workspace sign-in fixed, and security headers on every web surface.

  • Fix
    Sign-in for people in more than one workspace
    Someone who belongs to several workspaces could sign in successfully and then immediately hit “Signed in, but loading your session failed.” Sign-in now binds to the record for the workspace you are actually signing in to.
  • Fix
    Two-factor enrollment can no longer lock you out
    In a workspace that requires 2FA, a member could be left unable to finish enrolling and unable to get past it. Enrollment is now gated at startup and the token endpoint is exempt from enforcement, so required enrollment cannot deadlock.
  • Feature
    Security headers across the web tier
    The workspace app and the public site now send strict transport security, frame-blocking, referrer, and permissions headers. A content security policy runs in report-only mode ahead of enforcement.

Abuse limits, error handling, and faster session diagnosis.

  • Fix
    Rate limits count the real visitor
    Rate limiters were keyed on the CDN edge address rather than the actual client, so limits could apply to the wrong party entirely.
  • Fix
    Domain-verification abuse limits
    Domain verification now authenticates before rate limiting, caps attempts per workspace, counts brand-blocked attempts against that cap, and decodes internationalized domain names before the brand-impersonation check.
  • Fix
    The API stays up through an unexpected error
    Errors thrown inside a request now route to error handling instead of the process, with a last-resort process-level net behind them.
  • Fix
    The dashboard keeps its data through a blip
    A transient server error blanked the dashboard instead of leaving the last good numbers on screen while it retried.
  • Fix
    Honest failure reasons on domain verification
    A DNS lookup failure now reports what actually happened rather than a generic error, and the verification screen explains the fix in plain language and hides the setup form once a domain is verified.
  • Polish
    Faster session diagnosis
    A session’s written diagnosis is prepared as soon as its timeline lands, so opening a finished session shows the answer immediately instead of composing it on demand.
  • Polish
    Clearer public claims
    Corrected the public description of what AnchorGrid can see and do: sessions are not recorded, and the iOS control limitation is scoped to third-party apps rather than stated absolutely.

Verified workspace domains, a deeper session-diagnosis screen, and a new iOS release.

  • Feature
    Workspace domain verification
    Workspaces can prove control of their company domain with a DNS record. Verified domains show on the customer consent screen in the iOS app, so end users see exactly who is asking before they approve a screen share.
  • Feature
    Deeper session diagnosis
    The session detail screen now charts every outage on the timeline, totals the impact (outage count, time lost, worst gap), shows the network path the session took (direct or relayed, and why), and explains it all in plain language.
  • Feature
    Session timelines survive messy endings
    Diagnostics now reach the dashboard even when a session ends from Control Center, a phone call, or with the app in the background. Sessions nobody claimed no longer upload empty timelines.
  • Feature
    iOS 2026.7.12
    Verification status on the consent screen, fewer accidental session endings, cleaner session-ended notifications, and stability hardening.
    Rolling out via the App Store
  • Polish
    Snappier dashboard
    Dashboard and session-history views keep previous data on screen while refreshing, with proper loading placeholders instead of empty dashes.
  • Polish
    Faster public site
    The marketing site is now fully static and served from the edge; the app no longer ships marketing code.

Account, workspace, and session security tightened ahead of the beta.

  • Feature
    Brand-impersonation protection
    Workspace names and subdomains can no longer impersonate major brands, so AnchorGrid links stay trustworthy and safe to click.
  • Fix
    Password reset ends your other sessions
    Changing or resetting your password now signs out every other active session, so a lost or shared device cannot linger after you lock things down.
  • Fix
    Tighter session controls
    A remote session can only be ended and labeled by the technician who ran it or a workspace admin. Access is re-checked continuously, so removing a member cuts their access immediately.

Feedback channel, self-serve recovery, workspace deletion, and clearer legal terms.

  • Feature
    Report an issue
    Signed-in members can send feedback and bug reports straight from the workspace, with a reply routed back to them.
  • Feature
    Self-serve password reset
    Forgot your password? Request an emailed reset link right from the sign-in screen.
  • Feature
    Workspace deletion with recovery window
    Owners can delete a workspace. It is retained for 30 days so it can be restored before data is permanently purged.
  • Feature
    Clearer privacy and data terms
    Added a plain-language explanation of exactly what a technician can see during screen sharing, plus data-processing terms for IT administrators.

Error monitoring, a public status page, and a readiness health check.

  • Feature
    Error monitoring across the stack
    The iOS app, the browser viewer, and the API now report errors to monitoring with personal data scrubbed, so problems get caught fast.
  • Feature
    Live status page
    A public status page plus a footer status badge show API, website, and TURN-relay health at a glance.
  • Feature
    Readiness health check
    A new health endpoint verifies the database connection so a bad deploy fails safe instead of serving errors.

Invite-based private beta, live session detection, and auth polish.

  • Feature
    Private beta access
    Invite-based signup with a single-use access code and a 30-day beta window per workspace, with expiry reminders.
  • Feature
    Live session detection
    The dashboard now shows in-progress sessions in real time alongside the recent-sessions history.
  • Fix
    Email verification fix + rebrand
    Fixed a false "invalid link" error on email verification and refreshed the sign-in and account screens for AnchorGrid.

Session summary, settings redesign, iPad scaling, and App Store submission.

  • Feature
    Session-ended summary screen
    iOS shows a summary card after every remote session ends, including duration and disconnect reason. State survives a force-quit during an active session.
  • Feature
    Settings screen redesign
    Full-screen settings with card rows and an in-app browser for legal links. Marketing version shown in the footer only.
  • Feature
    iPad proportional scaling
    UI scales proportionally on 11" and 13" iPads so a 13" reads as a larger 11", not fixed-size content marooned on a big canvas. Share-code screen uses a leading grid with a wider info rail.
  • Feature
    Animated share-code flow and consent screen
    Unified nav bar, animated code reveal on the share screen, and a dedicated screen-share consent screen before the broadcast starts.
  • Feature
    Coaching view redesign
    Viewer now shows a device frame with a live step tracker during session setup. The Connecting step fires at the earliest signal (peer_joined).
  • Feature
    Device-name onboarding
    A new onboarding card lets users set a display name for their device before starting their first session.
  • Polish
    30 fps encoding cap
    H.264 encoder and frame pacer both capped at 30 fps after latency and memory testing on iPhone and iPad.
  • Fix
    Backgrounded app no longer plays code-respin tone
    The session-code refresh sound was audible when the app was in the background. It is now suppressed.

Instant recovery on network change, phone-call survival, and a 90-second give-up cap.

  • Feature
    90-second reconnect give-up cap
    Both the iOS extension and the browser viewer give up after 90 seconds of failed reconnection and surface a clear disconnect state. Both sides enforce the same cap so neither side waits forever.
  • Feature
    NWPathMonitor instant recovery
    A network path monitor in the extension fires a Tier-A ICE restart the moment network comes back up. WiFi-to-cellular handoffs and airplane-mode recovery no longer wait for a backoff timer to expire.
  • Fix
    Phone-call interruption recovery
    Screen share now survives an incoming phone call. The extension rebuilds the TURN-relay media path after the call ends rather than leaving the session dead.
  • Fix
    Viewer rebuilds peer connection on Tier-B reconnect
    A full reconnect with a new DTLS fingerprint now triggers a fresh RTCPeerConnection in the browser instead of a renegotiation on a stale connection.
  • Fix
    Airplane-mode hang fixed
    Extension reconnect no longer hangs when network drops completely. Backoff cancels correctly when the path restores.

Broadcast extension owns the entire WebRTC pipeline.

ArchitectureThe publisher moved out of the main app and into the broadcast extension.
The extension now owns the WebRTC peer connection, signaling WebSocket, reconnection, frame pacing, and token refresh. The main app is HTTP control plane only. The UNIX socket frame path, audio background mode, and main-app publisher are removed.
  • Feature
    In-extension WebRTC publisher
    ExtensionTransport runs a serial queue-confined coordinator for the WebSocket and RTCPeerConnection. SampleHandler pushes ReplayKit frames in-process with no inter-process socket.
  • Feature
    Extension self-refresh of signal tokens
    The extension calls /api/signal/refresh-token before a Tier-B reconnect with no main-app involvement required.
  • Feature
    HTTP consent flow
    The main app polls /api/session/:code/pending via a lightweight request poller. Consent and denial both go through HTTP; the extension finishes its own broadcast on remote session end.
  • Feature
    Extension memory diagnostics
    A memory probe surfaces live footprint data from the extension to the in-session screen so operators can track headroom against the extension memory ceiling.
  • Feature
    Dashboard connection-mix and live stats
    Dashboard constellation replaced with a connection-mix breakdown. Overview stats, historical metrics, and the active-technicians rail are all wired to live data.
  • Feature
    Appearance preference synced server-side
    Light/dark/system preference is stored per user and restored on next sign-in from any device.
  • Fix
    cq.sync reentrance trap eliminated
    A reentrant cq.sync call in broadcast-extension teardown was causing hangs on local stop. Replaced with locked helpers safe to call on the queue.

Admin redesign across all 7 surfaces.

HeadlineShared primitives library for the admin pages.
Settings sections, admin pills, policy rows, scope cards, segment bars. Every admin surface speaks the same vocabulary now. People, SSO, Audit log, Support access, Two-factor policy, Workspace settings, and Billing all rebuilt against it.
  • Feature
    Audit log split-panel view
    Click a row to load a detail card on the right with actor, target, IP, signature, and a Revoke action when applicable. All values rendered human-readable; no JSON in the UI.
  • Feature
    SSO method picker
    Pick your IdP from a tile grid. Microsoft 365 OIDC is the only wired one for now; SAML and Google land as we add them.
  • Polish
    Coming-soon overlay
    Aspirational sections (SCIM, webhooks, recording, regions, WebAuthn, step-up rules) render the design wrapped in a dashed-destructive frame so the road is visible even where the pavement isn't.

TLS TURN, observability, and signaling security fixes.

  • Feature
    TLS TURN on 5349
    coturn now terminates TLS at the Fly edge for TURN clients that block UDP 3478. Closes the strict-NAT gap on corporate networks.
    aux-server pinned to internal IP
  • Feature
    Structured metrics on signalling
    Every WebSocket lifetime, slot occupancy change, and p2p_connected event emits a [metric] line with setup_ms and candidate_pair. Ready for log aggregation.
  • Fix
    Six signaling security fixes (F1/F2/F4/F5/F6)
    WS hard-cap raised to 150 min, slot map capped at 10k, per-IP WS upgrade rate-limited, publisher tokens HMAC-derived per code, TURN credential mints rate-limited to 12/hr/sid.

relay-one.com → anchorgrid.io.

  • Breaking
    Brand and bundle ID renamed
    Relay-One → AnchorGrid across the iOS app, marketing copy, and the WebSocket signalling host. iOS bundle moved from com.relayone.app to com.anchorgrid.app; App Group moved from group.com.relayone.app to group.com.anchorgrid.app.
    requires App Store resubmission

Strict-NAT ICE convergence.

PostmortemSame-machine relay-to-relay packet drops on Fly.
coturn was auto-binding both Fly internal IPs (172.19.18.194 + .195), so packets bouncing between them got dropped. We now pin coturn's listening-ip + relay-ip to the highest 172.* IP at container start.
  • Fix
    TURN session convergence on corporate networks
    Symmetric NAT clients can now hold a TURN-relayed connection through path changes; previously they would fail to reconnect after a brief network blip.

coturn TURN server live in Ashburn.

  • Feature
    TURN fallback for strict-NAT
    Sessions that can't hold direct peer-to-peer (symmetric NAT, restrictive corporate firewalls) now relay through coturn on Fly without dropping. ICE picks the cheapest path that works.
  • Feature
    Per-session TURN credentials
    /api/turn/credentials mints ephemeral credentials at peer-connection construct time. Rate-limited per session id; credentials expire with the TURN_TTL_MS window.

SSO, 2FA, in-app audit.

  • Feature
    Per-tenant Microsoft 365 SSO
    Each workspace can register its own Azure app. JIT provisioning lands new sign-ins as Members; verified-domain enforcement gates which email domains can complete the OIDC flow.
  • Feature
    TOTP 2FA with tenant policy
    Workspace owners can require 2FA for all members, with a grace period for new joiners. Recovery codes, trusted devices, and per-role step-up rules.
  • Feature
    In-app audit log + CSV export
    Every category of action (session, auth, SSO, support access) flows into the same audit table. Role-aware visibility: owners see all, members see their own.
  • Feature
    Scheduled jobs with multi-replica safety
    pg_try_advisory_lock guards both the support-access-expiry and trial-expiring jobs so two API replicas don't double-fire.

Bare WebRTC + WebSocket signalling. LiveKit SFU removed.

BreakingThe video pipeline was rewritten end-to-end.
iOS now publishes NV12 frames over a custom UNIX socket from the broadcast extension to the main app, then through a single H.264 encoder into a bare RTCPeerConnection. The SFU encoder is gone. Thermal-throttling on the iPhone goes with it.
  • Feature
    Multi-tenancy
    Workspaces have their own subdomain. Membership-scoped reads on every database query. Auth, invites, accept-invite, role floors.
  • Feature
    HMAC-signed signalling tokens
    Publisher + subscriber WebSocket tokens are HMAC-SHA256 with per-code derivation. Rotates with SIGNAL_SECRET.
  • Feature
    Two-tier reconnect (Tier A ICE restart + Tier B full rebuild)
    NWPathMonitor triggers Tier A on WiFi↔cellular handoffs; Tier B reuses the original signalling token for cold reconnects within the 2-hour token TTL.