Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Privacy, telemetry & the community pulse

Participation should be private by default and deliberate. The reviewed server code now enforces a minimal usage-event contract for new writes. This is not a claim that the change is deployed or that historical data was cleaned.

If you opt into browser peer-to-peer sharing, peers can see your IP address. See P2P distribution for its controls and limitations.

What new telemetry writes retain

POST /telemetry accepts at most 4 KiB of strict flat EDN or JSON, with exactly three string fields: kind, attr, system. Kind must be in_use, installed or transferred; attribute and system must be an exact pair in the public package registry. The server stores those canonical values and its own timestamp and day. It does not retain submitted raw EDN/JSON (the legacy edn column gets constant empty text), region (NULL), identifiers or nonces. Unknown, duplicate, nested, missing and malformed fields are rejected, not silently persisted.

X-Region, X-Real-IP and X-Forwarded-For are ignored by this ingest. This is not evidence that connection IPs are absent from edge/network logs. Application request-parameter and query-bind logging is disabled on this write path; database and proxy logging configuration still needs review before deployment.

An anonymous global database quota admits at most 100 well-formed attempts per minute across API replicas, including unknown package pairs. There is no per-client identifier: one source can consume the quota or submit repeated events. This bounds writes, not Sybil attacks, people, machines or deduplicated daily use. Malformed requests are body-bounded but do not consume database quota; network request floods need separately managed ingress limits.

Invalid input returns 400, oversized bodies 413, global quota exhaustion 429, and actual database failures 503. Only a committed event receives 200. Legacy build herd_signal and raw-body internal writers fail closed; verified build evidence stays separate from usage events.

Historical raw EDN and caller-supplied regions may remain. No deletion, historical sanitization, retention job or production deployment is included. A separate 30-day retention proposal covers events, historical PII, backups and logs.

The solnix.privacy.enable master switch

The intended client contract below is private by default. The server review did not verify the client implementation or delivery behavior; these settings are not evidence that the current ingest is privacy-safe. Check your client implementation before relying on them. In this contract, true means fully private — no phone-home:

Note the inversion — this reads backwards. solnix.privacy.enable = true (the default) means NO data is sent. To join the community pulse you set it to false. Setting enable = false turns telemetry on, not off. We know this is a footgun; a positively-named solnix.telemetry.enable (default false) is planned to replace it.

solnix.privacy.enable = true;   # DEFAULT: fully private, phone-home OFF

A machine whose config never touches this stays completely private. Nothing is sent, nothing is shared.

To opt into the community pulse, set it to false. The individual features then default on, and you can pare any of them back:

solnix.privacy.enable = false;        # opt into the community pulse

# with privacy off, these default true — override any individually:
solnix.telemetry.enable          = true;   # group: all phone-home
solnix.telemetry.census.enable   = true;   #   platform / active-user census
solnix.telemetry.packages.enable = true;   #   transferred / installed / in-use
solnix.cache.seed.enable         = true;   # P2P: seed built packages (BitTorrent)
solnix.site.p2p.enable           = true;   # P2P: browser WebRTC site sharing

The effective rule, in plain language: a feature is active only when the master switch is off and its group is on and the feature itself is on — (not privacy.enable) && telemetry.enable && <feature>.enable. The master switch always wins. Someone who never touches config is fully private; someone who opts in gets everything, then can turn off any piece.

See Peer-to-peer distribution for cache.seed and site.p2p.

Public aggregates and proposed safeguards

The metrics changes expose 30-day reported usage-event counts, not numbers of people or machines. Public count fields below five events are suppressed. Five events can all come from one source: this is not k-anonymity of five machines. Ranking still uses the existing weighted score, so count suppression is not a guarantee against inference from rank or inclusion.

Pulse reports rollup refresh time when known, not upstream inventory freshness. Unique-user totals are unmeasured. Small or missing regional buckets do not prove zero usage. Regional buckets can reflect historical, untrusted data only; new writes supply no region. Public metrics views expose aggregates, not raw bodies.

Edge-derived coarse regions, daily deduplication, and machine-based anonymity were design proposals, not implemented guarantees. No rotating nonce or new identifier is introduced by these fixes. Retention limits and any removal of previously retained raw bodies require separate approval.

Both EDN and JSON are supported, posted to https://search.solnix.io/telemetry, for example:

{:kind "in_use" :attr "hello" :system "x86_64-linux"}

The example pair must actually exist in the public registry. No client timestamp, region, census, nonce, personal field or store path is accepted.

Why report usage

Reported events can help identify packages receiving use or installation reports. They cannot establish community size or growth in distinct users. Participation should be deliberate and private by default; enforceable ingest safeguards must come before an unconditional privacy promise.

Where to see the results

  • Community pulse: reported package events, regional event aggregates and rollup refresh time, not an active-machine census.
  • Package search: popularity combines reported usage events and dependency information; it is not a count of users.