Using One Connect

Phone and alerts

Answer questions and approvals from your phone through a private, authenticated tunnel, and route alerts to the channels you choose. Everything is off until you turn it on.

What you get on a phone#

The dashboard is an installable web app. On a paired phone it shows:

  • Now (/phone): what needs you, every agent's status and included-usage meters, alerts, and the kill switch.
  • Questions and Decisions, with their evidence. Anything irreversible asks for a second confirmation.
  • Live transcripts (/runs/<id>): the full redacted transcript of a run, readable on a narrow screen. Reading only.
  • Brief and reports (/reports): brief, timeline, morning report and an exportable standup.

It is built for one thumb: 44-pixel targets, one column, nothing hover-only, and a bottom tab bar. A paired phone is bound to one project; each project has its own engine, cookie and pairing. From a phone you can engage the kill switch but not release it.

Install it as an app#

The page ships a manifest, icons and an offline page. Your browser decides whether it installs: on iPhone use Share → Add to Home Screen; in Chrome or Edge use the install icon. Phone and alerts shows only what the browser reports.

Offline. The service worker caches only the offline page, the manifest and the icons. No API response, transcript, prompt, source, evidence, credential, cookie or link is stored on the device. Offline, the app says so and refuses every change; nothing is queued or replayed later.

Turn on remote access#

Remote access is off by default: nothing listens beyond 127.0.0.1.

  1. Open Settings → Phone and alerts on the Mac and switch Remote access on. This opens nothing.
  2. Review the scopes a phone may get. Adding a scope needs a new pairing; narrowing applies immediately and closes stale connections.
  3. Review exact plan (dry run) shows the commands, what is exposed, the teardown, warnings and a digest. Nothing runs.
  4. Request tunnel launch creates a Decision bound to that exact plan. It expires in 10 minutes, is voided if settings change, works once, and needs a second confirmation. Only then does the tunnel start.
  5. Create single-use pairing link and open it on your phone. Revoke one phone or all phones at any time; turning remote access off revokes everything and stops the tunnel.
ScopeAllows
readStatus and reports
transcriptRun transcripts, which can quote source
decisionsAnswering this project's Decisions: merge, Docker, environment, release, cost, settings, connector and notification actions
kill_switchEngaging (never releasing) the kill switch
remote_decisionsAdditionally, tunnel launch Decisions. Off by default; requires decisions.

No scope opens source diffs, connection or Docker management, credentials, the vault, project management or configuration.

Tailscale Serve#

The tunnel adapter uses Tailscale Serve, privately:

tailscale status --json
tailscale serve --bg --https=8443 http://127.0.0.1:<daemon port>
tailscale serve --https=8443 off     # teardown: removes exactly that entry

It never uses Funnel or any public or wildcard listener; such a plan is refused. It changes this Mac's Serve configuration for that HTTPS port only, with no ACL, key or device changes, and One Connect never installs or signs in to Tailscale. Port 8443 is the default so an existing 443 entry is not overwritten; each project's engine needs its own port. Which of your devices can reach it is decided by your Tailscale ACLs.

How phone access is protected#

GuardHow
Separate credentialsOver the tunnel, only a paired phone session works. The Mac's cookie, install token, WebSocket tickets and run tokens are refused.
PairingA 256-bit single-use token in the URL fragment, so it is never sent to a server, logged or leaked through a Referer. It expires in minutes and is removed from the address bar before use.
Session cookie256-bit, stored hashed, HttpOnly, SameSite=Strict, __Host- and Secure, named per project, with session and idle timeouts and a cap on phones
CSRF and OriginChanges need a CSRF header derived from the cookie and an exact Origin; sockets need the exact Origin
Brute force5 failed pairings in 10 minutes lock pairing for 15 minutes. Creating a link on the Mac clears the lock.
Isolation and auditSessions are bound to one project. Revoking closes open sockets. Events record launches, pairings, failures, revocations and refused requests, never tokens.
Honest statusTunnel state, engine readiness and reachability are shown separately. "Up" never means reachable until a paired phone actually connects.

Notifications#

Alerts come from recorded events: stalled runs, aged approvals and Decisions, usage limits, check and infrastructure failures, and finished work. They are deduplicated with a cooldown, redacted, and always written to a durable local inbox.

ChannelDefaultNotes
Local inboxAlways onPart of the event log; survives restarts
macOS bannerOffSent with osascript. macOS does not report permission, so the page says permission unknown.
BrowserOffShows the alert title when the browser granted permission
JSON push gateway, chat webhookOffA minimal JSON POST: id, kind, severity, short title and time

Outbound channels never send automatically. Each outbound message needs its own Decision with a second confirmation, valid for one attempt within ten minutes, bound to the exact payload and URL. Payloads use issue keys only: never issue titles, transcripts, prompts, source or secrets. Redirects are never followed, and an interrupted delivery is never retried automatically.

Quiet hours (local time or an IANA time zone, which may wrap midnight) hold banners, browser notifications and outbound messages; the inbox still records them. Leaving quiet hours never sends held messages.

Edit this page on GitHub