Entroly product-health telemetry is off by default. It starts only after an operator gives explicit consent:
entroly telemetry preview
entroly telemetry on --endpoint https://telemetry.example/v1/events
entroly telemetry status
Without an endpoint, consent creates only a bounded local queue and uploads
nothing. ENTROLY_DISABLE_TELEMETRY=1 and ENTROLY_AIR_GAP=1 always override
stored consent. CI and test processes are excluded unless separately enabled.
The wire format is a closed allowlist. A consenting installation can report:
ValueError or OSError, if error events remain enabledCommand, surface, error, and coarse value categories are deduplicated per UTC day. Savings contributions carry random event IDs so a retried upload cannot be counted twice. The reported savings number is a rounded-down lower bound; event counts must not be interpreted as command or request frequency.
Entroly does not put any of the following into product-health events:
The network endpoint or reverse proxy necessarily sees a connection source IP while accepting a request. The bundled collector does not read or store it and runs with access logging disabled. Operators must also disable upstream access logs or apply an appropriate short retention policy.
A positive token-reduction bucket means Entroly measured fewer estimated tokens
after its transformation. SDK and MCP-style local operations remain
local_estimate: Entroly cannot prove that their output reached a paid model.
Proxy transformations can be provider_bound_estimate; a positive modeled cost
signal additionally requires a configured rate for the provider-bound model.
Neither signal is a provider invoice, a billed-usage comparison, or a promise that response quality improved. Reports keep these claims separate:
ENTROLY_TELEMETRY_TRUST_PROXY_ENV=1entroly telemetry off removes local consent, queue, status,
markers, and random seed, and requests deletion of the four recent monthly
pseudonyms from a configured collectorRemote deletion removes contributions still inside the collector retention window. After a contribution has been folded into the identifier-free archive, it can no longer be linked to an installation or individually subtracted. This is the tradeoff that permits a cumulative counter without indefinitely retaining pseudonymous event rows. Disabling telemetry also removes the unsent local quantization remainder.
The collector binds to loopback and should sit behind an authenticated HTTPS reverse proxy. In PowerShell:
$env:ENTROLY_TELEMETRY_INGEST_TOKEN = "replace-me"
$env:ENTROLY_TELEMETRY_ADMIN_TOKEN = "replace-me-too"
python -m entroly.telemetry_collector --db C:\entroly-data\product-health.db
On macOS or Linux, use export NAME=value. Keep the admin summary endpoint
private. If ingest is intentionally tokenless for public clients, enforce
request-size limits and rate limiting at the reverse proxy.
The private collector summary exposes only aggregates: active monthly pseudonym counts, activation counts, coarse errors, command reliability, platform-family health, and coarse benefit evidence. It never returns raw events or pseudonyms.
GET /v1/public-savings requires no admin credential and returns only the two
cumulative lower-bound totals plus an update timestamp and fixed evidence/privacy
labels. It exposes no pseudonym or contribution count. Browser access is allowed
only for the configured ENTROLY_TELEMETRY_PUBLIC_ORIGIN (the Entroly GitHub
Pages origin by default), and responses are cacheable for 30 seconds.
Telemetry cannot observe a package installation that fails before Entroly first starts. Registry downloads, release CI, and user-submitted diagnostics must cover that blind spot; the report must not misclassify a download as a working install.
To combine those aggregate observations with registry downloads without pretending downloads are users:
python scripts/adoption_report.py \
--collector-summary-url https://telemetry.example/v1/summary?days=30
The report labels the resulting ratios as observed opt-in diagnostics, never as an actual unique-user adoption rate.
Python and modern npm package managers do not provide a dependable Entroly uninstall callback. Pip documents package removal as a package-manager action, and npm explicitly states that uninstall lifecycle scripts are not implemented:
Entroly therefore provides an honest guided path instead of pretending every removal can be observed:
# Python installation: optional survey, then pip uninstall
entroly uninstall
# Inspect the exact response and command without sending or changing anything
entroly uninstall --dry-run \
--reason runtime_error --benefit no --surface mcp --duration 1_7d
# npm, Docker, or another removal path: survey only, then use that manager
entroly uninstall --feedback-only
npm uninstall -g entroly
The survey has no free-text field. It contains only:
Interactive sending defaults to No and shows the collector origin first.
For non-interactive use, all four fields and --send-feedback are required.
ENTROLY_FEEDBACK_ENDPOINT or --endpoint selects the HTTPS collector, but
neither causes a submission without the interactive confirmation or explicit
flag. Air-gap and hard-disable policies still win.
The response is sent synchronously once and is never queued on failure. When ongoing telemetry is enabled and the destination is the same configured collector, it uses the current monthly pseudonym so the private aggregate report can count how many exiting installations previously observed a benefit or error. A different or one-time collector receives a random one-event pseudonym that is never persisted. The guided flow revokes local telemetry consent before the package is removed, so a later reinstall requires fresh consent.
--delete-remote-telemetry requests deletion of recent linked telemetry before
sending any separately confirmed one-time response. Collector retention still
applies to that new response. Users who do not want a retained exit response
should decline the survey; no uninstall behavior is affected.
The private aggregate summary exposes exit-response counts, fixed reasons,
self-reported benefit, primary surfaces, duration buckets, OS-family counts,
and counts with prior benefit/error observations. It never exposes response
rows, pseudonyms, or cross-tabs containing machine-identifying data. Direct
pip uninstall, npm uninstall, deleted containers, and failed installations
remain invisible; registry downloads must never be used to fabricate an exit or
retention rate.