Repository navigation
feat(core): opt-out anonymous usage telemetry #295
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| # ADR-0044: Opt-out anonymous usage telemetry | ||
|
|
||
| **Date**: 2026-10-12 | ||
| **Status**: Accepted | ||
|
|
||
| ## Context | ||
|
|
||
| We have no idea how many deployments run Openora, which versions they're on, or whether they | ||
| have players. npm download counts mix CI installs, mirrors and bots, and say nothing about a | ||
| server that keeps running. We want a count of active installs that respects operators: no | ||
| personal data, visible, and easy to switch off. | ||
|
|
||
| ## Decision | ||
|
|
||
| The server sends a small anonymous report to an Umami collector at `telemetry.openora.ai`, on | ||
| start (at most hourly per deployment, guarded by a Redis key) and daily through a `JOB_QUEUE` | ||
| scheduler. The scaffolder sends one report per project created. What each report holds, and | ||
| every way to turn it off, is in [usage telemetry](../platform/telemetry.md). | ||
|
|
||
| - **On by default, opt-out.** An opt-in count only measures the people who read the docs. The | ||
| switch is an env var, the `DO_NOT_TRACK` standard, or a `createApp` option, and the server logs | ||
| how to use it at boot. | ||
| - **The instance id lives in Postgres**, in a single-row engine table next to the outbox. | ||
| Replicas racing on first boot converge on one id. Redis was rejected: a flush would mint a new | ||
| id and inflate the count. | ||
| - **Player counts go through the activity tracker port**, so the runtime never reads the player | ||
| table, and a deployment without the player module reports empty counts. | ||
| - **The Umami event format, not a custom collector.** The maintainers already run Umami, and its | ||
| distinct id makes "unique visitors" equal active installs. The hostname is dedicated so a | ||
| released version keeps a working URL whatever runs behind it. | ||
| - **No install hook.** Scanners flag postinstall scripts, pnpm 10 blocks them, and CI installs | ||
| would swamp the count. | ||
|
|
||
| ## Consequences | ||
|
|
||
| - A public client can't authenticate, so anyone can post fake reports. Rate limits and a body cap | ||
| sit at the edge in front of the collector, and the counts are treated as approximate. | ||
| - A failed report is dropped with a warning; nothing retries, and boot never waits on it. | ||
| - Changing what a report carries means updating the usage telemetry page in the same change. | ||
| - The scaffolder copies the payload and opt-out rules instead of importing the core runtime; the | ||
| two are kept in step by hand. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| # Usage telemetry | ||
|
|
||
| Openora reports anonymous usage so we know how many installs are running and which versions | ||
| and runtimes they're on. It's on by default and takes one environment variable to turn off. | ||
| The decision is in [ADR-0044](../adr/0044-opt-out-anonymous-usage-telemetry.md). | ||
|
|
||
| ## What is sent | ||
|
|
||
| Every report carries the same fields and nothing else: | ||
|
|
||
| - a random instance id, generated on first boot and stored in the database, so one deployment | ||
| counts once however many replicas it runs | ||
| - the `@openora/core` version | ||
| - the Node.js version, the operating system and the CPU architecture | ||
| - how many players were active in the last day and the last 30 days, as two plain counts (empty | ||
| when the player module isn't loaded) | ||
|
|
||
| No hostname, IP-derived data, player id, operator name, config value or request data is sent. | ||
| The collector sees the sending IP like any HTTP server does. Umami turns it into a country and | ||
| doesn't keep the raw address. | ||
|
|
||
| ## When | ||
|
|
||
| - On server start, at most once an hour per deployment, so a crash loop or a rolling deploy | ||
| doesn't flood the collector. | ||
| - Once a day from the job queue, so a server that runs for months still counts as active. The | ||
| queue fires it once per day across all replicas. | ||
| - Once when `npm create @openora` scaffolds a project. The scaffolder sends a fresh random id | ||
| each run, so every run counts as one project, whoever ran it. | ||
|
|
||
| A report that fails is dropped with one warning in the log. Nothing retries, and a failure | ||
| never delays or breaks boot. | ||
|
|
||
| ## Where | ||
|
|
||
| Reports go to `https://telemetry.openora.ai`, an [Umami](https://umami.is) instance run by the | ||
| Openora maintainers. `OPENORA_TELEMETRY_URL` points them somewhere else, for example a collector | ||
| of your own. | ||
|
|
||
| ## Turning it off | ||
|
|
||
| Any one of these switches it off. Nothing is sent and the daily job is removed from the queue: | ||
|
|
||
| ```bash | ||
| OPENORA_TELEMETRY_DISABLED=1 # or the cross-tool standard DO_NOT_TRACK=1 | ||
| ``` | ||
|
|
||
| ```ts | ||
| createApp({ ...config, telemetry: false }); | ||
| ``` | ||
|
|
||
| ```bash | ||
| npm create @openora my-app -- --no-telemetry | ||
| ``` | ||
|
|
||
| It's always off under `NODE_ENV=test` or when `CI` is set, so pipeline and e2e runs don't count as | ||
| installs. The server logs one line at boot when telemetry is on, with the switch to turn it off. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
packages/core/src/pam/profile/drizzle/migrations/0010_fine_mastermind.sql
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| CREATE INDEX "player_last_seen_at_idx" ON "player" USING btree ("last_seen_at"); |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.