Docs

Privacy model

The phone-to-engine channel uses a WebSocket, sealed end to end with AES-256-GCM. Keys are derived per connection and per direction, so a captured frame cannot be replayed on the next connection.

The pairing key lets a new device prove it may enrol. Content keys are sent to enrolled devices inside the sealed channel, not in plaintext to the app-server. The app-server forwards sealed frames without decrypting their contents. It can see connection metadata, including engine and device identifiers, timing and frame sizes. There is no unsealed fallback for the phone-to-engine channel.

New-device enrolment requires the pairing key, localhost included. Returning devices authenticate with their enrolled device key. Revoked devices are refused at the handshake and when opening a relay connection.

Voice transcription and synthesis run on your machine. Audio and text travel between your phone and engine over the sealed channel.

Local and Tailscale access

Open the app from your own app-server on your machine, or over your Tailscale network. Use the Tailscale HTTPS link for phone access. Your app-server stays in the connection path, forwarding sealed frames between phone and engine. If it stops or becomes unreachable, chats must reconnect before they can send or receive.

The pairing link carries the key in a URL fragment, which browsers do not send in HTTP requests or the Referer header. Keep that link private, and trust the machine serving the app: its JavaScript handles your keys.

This website

callyourcode.com counts visits with Majdooritics, Google Analytics and PostHog, so we can see what people read. That covers this website only: the app and the engine send nothing to these analytics services.