Privacy
Saykeep is a local-first application. Your audio, recordings, transcripts, and speaker labels are processed on your machine and stored only in your configured storage folder; summaries come from an OpenAI-compatible endpoint you configure — a local server by default, or a service of your choice with your own API key. This is not a promise you have to trust — it is a property you can verify.
Recording is always visible — there is no covert mode
Saykeep records out in the open. Whenever meeting capture is active, an always-on indicator shows it: the menu-bar icon, a status line with elapsed time and live audio meters, and the recording card. No setting or code path can suppress it. There is no hidden, discreet, or low-visibility recording mode in the product; this is a locked, test-enforced invariant, not a UI default that could be quietly changed. The first meeting you record also opens a consent notice, because in some places every participant must agree before you record (see the FAQ). Obtaining that consent is your responsibility; Saykeep’s job is to make recording impossible to miss.
You decide what’s kept
Saykeep doesn’t hoard recordings. Once a meeting is transcribed, it can delete the audio for you — asking after every meeting, or automatically cleaning up audio older than a number of days you choose. The guard rail: audio is deleted only when a successful transcript exists, and transcripts and summaries are never deleted automatically. You can also delete any meeting entirely from the recordings browser, or erase your Saykeep content — recordings, models, settings — in one guarded step (you type ERASE to confirm). It’s all plain files in your own folder; what stays is up to you.
The short version
127.0.0.1 by default). On first run, the speech models download once (full list below).The one exception during normal use — the update check
Saykeep can check whether a newer version exists. This check is off by default and never opens a connection unless you turn it on. When enabled, it makes at most one anonymous request per day to GitHub Releases — no version string, no machine id, no identifier of any kind. It only notifies you; it never downloads or installs anything on its own. Leave it off and Saykeep makes no update calls at all.
How to verify
sudo ss -tunp | grep saykeep or lsof -i -a -p <pid>. With summaries pointed at a local endpoint and models already downloaded, you will see zero outbound connections during normal use.# NETWORK.md — every connection Whisperer can make Whisperer is a **local-first** application. Your audio, recordings, transcripts, and summaries are processed on your machine and stored only in your configured storage folder. This document is an exhaustive, behavior-verifiable inventory of **every** network connection the app is capable of making — nothing else happens. You do not have to take our word for it: run a network monitor (Little Snitch on macOS, `lsof -i` / `ss -tunp` on Linux, a firewall log on Windows) and confirm the app opens only the connections listed here. *This file is kept in sync with the code. If you find an outbound connection not listed here, that is a bug — please report it.* ## The complete list | # | Host | When | What is sent | Contains your data? | Avoidable? | |---|------|------|--------------|---------------------|------------| | 1 | **The LLM endpoint you configure** (`llm.endpoint_url`; default `http://127.0.0.1:8080/v1` — a server on your own machine) | When a meeting summary is generated, and a `/models` health probe when you test the connection | The meeting **transcript text** (for summarization) or a models list request (for the probe) | **Yes — transcript text.** It goes only to the endpoint *you* set. By default that is a local server and nothing leaves your machine. If you point it at a cloud API, your transcript goes there **by your choice** | Yes — disable summaries / leave the endpoint unset. Meetings still record and transcribe fully locally | | 2 | **huggingface.co** (and its model CDN) | First time a model is needed: the Whisper-family speech-to-text models and, if you enable diarization, the speaker models | A standard model **download** request; for the diarization models, your Hugging Face **token** in an `Authorization` header (only if you provide one) | No — these are downloads *to* your machine. Your token authenticates the download; no audio/transcript is uploaded | Partly — once models are cached locally they are not re-downloaded. Diarization is optional | | 3 | **huggingface.co/api** (token check) | Only when you click "Test" on the Hugging Face token field in the wizard/settings | Your HF token in an `Authorization` header, to verify it can access the diarization model | No | Yes — it only runs when you test the token | | 4 | **api.github.com** | At most once/day, ONLY if you enable Check-for-updates (off by default) | An anonymous latest-release request — no version string, machine id, or identifier | No | Yes — never runs unless you turn it on | *Row 4 note: this check is off by default and never opens a socket while off.* That is the entire list. ## What Whisperer **never** does - **No telemetry, analytics, crash reporting, or usage tracking.** No analytics SDK is linked into the app — and you can hold us to it from the outside: the rows above are everything, and the wire is checkable. - **No accounts, no login, no cloud sync.** There is no Whisperer server. Nothing is uploaded. - **Your recordings, transcripts, and summaries are never sent anywhere** except the transcript text to the LLM endpoint *you* configured (row 1). They are stored only in your storage folder. - **No license phone-home.** License keys are verified **offline** against a compiled-in public key — no activation server, no network call, ever. - **The diagnostics export** (Settings → Advanced) writes a **local file** you choose whether to share; it makes no network call, and it redacts secrets. ## Local helpers are not network connections Whisperer runs some local subprocesses — `pw-record` (Linux system audio), the bundled `whisperer-syscapture` (macOS system audio), `osascript`/`caffeinate` (macOS), and your OS's file-reveal command. These are **on-device** and open no network sockets. ## How to verify 1. **Watch it live:** macOS → Little Snitch; Linux → `sudo ss -tunp | grep whisperer` or `lsof -i -a -p <pid>`; Windows → Resource Monitor / firewall log. With summaries pointed at a local endpoint and models already cached, you will see **zero** outbound connections during normal use. 2. **Inspect your config:** Settings → Advanced → "Export diagnostics…" shows your resolved `llm.endpoint_url` (credentials redacted) so you can confirm where summaries would go. 3. **Hold us to the contract:** Whisperer is closed-source, so instead of "read the code," this file *is* the auditable surface — the only things that ever open a socket are the rows above. If you ever observe a connection that is not listed here, that is a bug; report it and we will treat it as one. ## Planned additions (not yet active in the app) - **Self-hosted model mirror:** a Whisperer-controlled download host that will serve the diarization models **without a Hugging Face token**. Until it is live, diarization models come from huggingface.co (rows 2–3). Like rows 2–3, it would only ever *download* models to your machine — nothing is uploaded.
Verify it yourself — the walkthrough
macOS — Little Snitch
Install Little Snitch (or its free companion, Little Snitch Mini), open its network monitor, and use Saykeep normally — dictate, record a meeting, generate a summary against your local endpoint. Saykeep’s row stays at zero outbound connections.
Linux — ss / lsof
# (no output — zero sockets)
$ lsof -i -a -p $(pgrep saykeep)
# (no output — zero sockets)
If you ever see a connection that isn’t on the published list, that’s a bug — tell us.