diff --git a/docs/privacy/lf-telemetry.md b/docs/privacy/lf-telemetry.md index b880803..51ef72b 100644 --- a/docs/privacy/lf-telemetry.md +++ b/docs/privacy/lf-telemetry.md @@ -1,49 +1,59 @@ --- ## *LoopFollow* Anonymous Telemetry -*LoopFollow* can send a small anonymous report once a day so the -maintainers can see which app and *iOS* versions are still in active use. -The data helps make decisions like when it's safe to drop support for -older *iOS* releases. **No glucose data, no credentials, no logs leave -your device.** - -This is opt-out: the first time the app comes to the foreground after -installing or updating to a version that supports telemetry, you'll see -a one-time prompt to choose Yes or No. You can change your mind any -time in *Settings* > *General Settings* > *Diagnostics*. +*LoopFollow* sends a small anonymous report to the maintainers, once a +day and after you install a new version. It tells them which app and +*iOS* versions are in active use and how quickly people update. That +helps decide, for example, when it's safe to drop support for an older +*iOS* release, and shows early whether a new version is working well. +**No glucose data, no credentials, no logs leave your device.** + +Usage stats are **on by default**. You can turn them off at any time in +*Settings* > *General Settings* > *Diagnostics* > *Send anonymous usage +stats*. If you already chose **No thanks** or turned the toggle off in +an earlier version, that choice is kept. When usage stats are off, +nothing is sent. - - - ## What is sent -A typical check-in looks like this — you can see the exact JSON your -own install would send under *Settings* > *General Settings* > -*Diagnostics* > *What's sent*. +A typical report looks like this. You can see the exact report your own +install would send under *Settings* > *General Settings* > *Diagnostics* +> *What's sent*. | Field | Example | Notes | |:--|:--|:--| -| App version | `6.0.7` | | -| Build date | `2026-04-15` | | +| App version | `8.0.1` | | +| Build date | `2026-11-03` | The day this copy of the app was built. | +| Build commit | `46a9ed3` | A short code that identifies the exact source code the app was built from. | | TestFlight or not | `true` / `false` | Whether the install came from TestFlight or a local Xcode build. | -| Instance | `LoopFollow` / `LoopFollow_2` / ... | If you have multiple *LoopFollow* installs side by side, this distinguishes them. | -| IDFV | Apple per-vendor UUID | Apple's `identifierForVendor` — opaque, scoped to *LoopFollow*'s bundle prefix, and resets when all of this developer's apps are removed from the device. Combined with the *Instance* field above, identifies a specific install. | +| Instance | `LoopFollow` / `LoopFollow_.Second` / ... | If you have more than one *LoopFollow* installed side by side, this tells them apart. | +| IDFV | Apple per-vendor UUID | Apple's `identifierForVendor`: an opaque code that is the same for all apps from this developer on your device, and resets when all of them are removed. Together with *Instance*, it identifies one install. | | Device | `iPhone15,2` | Apple's hardware identifier (not the marketing name). | | Platform | `iOS` / `iPadOS` / `macCatalyst` | | | iOS version | `17.5` | | -| Following app | `Loop` / `Trio` / ... | Which closed-loop app *LoopFollow* is following, if known. Field is omitted when not yet detected. | +| Following app | `Loop` / `Trio` / ... | Which automated insulin delivery app *LoopFollow* is following, if known. Left out when not yet detected. | | Uses *Dexcom* | `true` / `false` | Whether *Dexcom Share* is configured. **No username or password.** | | Uses *Nightscout* | `true` / `false` | Whether a *Nightscout* site is configured. **No URL or API token.** | -| Background-refresh method | `Silent Tune` | Which background-refresh strategy is selected. | +| Background-refresh method | `Silent Tune` | Which background-refresh method is selected. | | Display units | `mg/dL` / `mmol/L` | | -| Remote-command type | `none` / `Loop APNS` / ... | Which remote-command path is configured. | +| Remote-command type | `None` / `Loop APNS` / ... | Which remote-command method is configured. | | Appearance | `dark` / `light` / `system` | | | Calendar / Contact integrations | `true` / `false` | Whether those features are turned on. | -| Cold launches in past 7 days | `12` | A count of process restarts; high values can flag stability issues. | +| Cold launches in past 7 days | `12` | How many times the app was started from scratch in the last 7 days. High values can point to stability problems. | + +Each report also says what triggered it, for example `cold_launch` (the +app started), `foreground` (the app was opened), `build_change` (first +start of a new version) or `timer` (the daily check). If the previous +attempt to send failed, it includes a short error category such as +`checkin_request_failed`. The server adds two fields when it stores each report: * `receivedAt` — the time the report was received. -* `dayBucket` — a date label (e.g. `2026-04-29`) used to deduplicate. +* `dayBucket` — the date (in UTC), used to keep at most one report per + install, day and version. - - - @@ -57,47 +67,47 @@ Specifically and explicitly: * No time zone. * No remote-command secrets, no APNS keys. * No GPS or location data. -* **No logs.** Logs are never sent automatically. The existing *Settings* > *Logs* sharing flow is unchanged and only triggered by you. +* **No logs.** Logs are never sent automatically. The *Settings* > *Logs* sharing flow is unchanged and only triggered by you. -The receiving server also does not log your IP address — the *NGINX* -edge zeroes the last octet of *IPv4* addresses and only retains the +The receiving server also does not log your IP address: the *NGINX* +edge zeroes the last octet of *IPv4* addresses and keeps only the `/64` prefix of *IPv6* addresses before anything is written to disk. - - - ## Where it goes -Reports are sent over *HTTPS* to **`https://lf.bjorkert.se/api/telemetry/checkin`**, -which is self-hosted by the maintainer. There is no third-party -analytics service involved. +Reports are sent over *HTTPS* to **`https://lf.bjorkert.se/api/telemetry/`**, +which is self-hosted by the maintainer. No third-party analytics +service is involved. Stored reports are kept on that server and are +not shared. - - - ## How to opt out -The toggle lives at *Settings* > *General Settings* > *Diagnostics* > -*Send anonymous usage stats*. Turning it off is immediate and persistent. +The toggle is at *Settings* > *General Settings* > *Diagnostics* > +*Send anonymous usage stats*. Turning it off takes effect immediately +and stays off. From then on nothing is sent. The *Diagnostics* section also has: -* *What's sent* — renders the exact *JSON* your install would send right now, - with a *Copy* button if you want to inspect it more closely. +* *What's sent* — shows exactly what your install would send right now, + with a *Copy* button if you want to look at it more closely. * *Privacy* — a shorter in-app version of this page. - - - ## How often -A check-in is sent at most once every 24 hours, or once after a new -build is installed (whichever fires first). It runs in the background -while the app is active or refreshing in the background — *LoopFollow* -schedules the next check-in based on when the last one was actually -sent, so a relaunch a few hours after the previous send simply waits -out the remainder of the 24 hours. +At most once every 24 hours, plus once on the first start of a new +version. *LoopFollow* checks whether a report is due when the app +starts, when you open it, and while it refreshes in the background, so +a report goes out even if the app is rarely opened. -If a send fails (network error, the server is unreachable, etc.) the -last-sent timestamp is not updated, so the next scheduled check tries -again. +If sending fails (no network, server unreachable, and so on), the app +waits an hour before it tries again, and the next report includes the +error category so the maintainers can see why reports go missing. - - - diff --git a/docs/setup/lf-setup.md b/docs/setup/lf-setup.md index ccfee23..a41c123 100644 --- a/docs/setup/lf-setup.md +++ b/docs/setup/lf-setup.md @@ -27,8 +27,7 @@ The guide steps through: 7. **Recommended alarms** — a set of useful alarms is offered with sensible defaults and a single control each: **Low glucose**, **Urgent low**, **High glucose**, **Fast drop**, and **Missed readings**. When following *Nightscout*, alarms that rely on loop/uploader data are also offered: **Not looping**, **Looping phone battery**, **IOB**, **COB**, **Sensor change**, **Pump change**, and **Pump insulin**. Alarm types you already have are not offered again. 8. **Tabs** — arrange which features sit in the tab bar. You can always reach everything through the [Menu](#menu-screen). 9. **Notifications** — *LoopFollow* explains why it needs notifications for alarms, then asks iOS for permission. Choose **Enable Notifications** or **Not now**. -10. **Privacy** — optionally share anonymous diagnostics to help improve *LoopFollow*. Choose **Yes, send anonymous stats** or **No thanks**; you can change this any time in Settings → General → Diagnostics. See [Telemetry](../privacy/lf-telemetry.md){: target="_blank" } for exactly what is and isn't shared. -11. **You're all set** — a summary with a **Finish** button, plus a few features worth exploring next. +10. **You're all set** — a summary with a **Finish** button, plus a few features worth exploring next. ![Choose a data source step](img/onboarding-data-source.png){width="280"} ![Nightscout connect step](img/onboarding-nightscout.png){width="280"}