Ctrl K
ComunidadGuías…

docs/telemetry.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Telemetry and Feedback

Anonymous usage data helps improve self-host: which Apps people install, which
Setup steps are slow, and where commands fail. Release builds send it to EU
PostHog through `https://hog.ajnart.dev`. Development builds and CI send nothing.
There is no public dashboard yet; one may come later.

## What it is for

The data is used only to see how self-host is used, such as which Apps people
install and where Setup and Onboarding break, and to debug failures. Only the
maintainers see it. It is never sold, rented or shared with third parties, and
never used for advertising.

## What is sent

Only these four things. A command that succeeds sends nothing.

- **An onboarding summary**, when you approve Onboarding's plan: your Experience
  level (`new` or `advanced`), the glyph set (`nerd-font` or `simple`), whether
  you skipped the intro, whether the machine check warned (`ok` or `warn`), how
  long Onboarding took, and the Catalog App and Recipe IDs and Access choice
  (`home` or `local`) you picked. Nothing is sent if you quit before approving.
- **Errors**, when a command fails or ends incomplete: the command name,
  duration, Catalog App and Recipe IDs, step IDs, outcomes and durations, and a
  PostHog `$exception` with the error type, a fixed description, a stable
  fingerprint, and in-app function names, module-relative files and line
  numbers. Panics are unhandled exceptions, flushed before the original panic
  continues. Install approval rejections, Cloudflare plan input errors, a
  missing Project, a Dashboard closed by a signal and `doctor` findings send
  nothing. Warning and error steps also send fixed-text OTLP log records with
  the step and command IDs.
  These are not App logs, raw error messages or distributed traces.
- **Agent App requests.** When an agent is asked for an App that is not in the
  Catalog, it runs `self-host apps request "<name>"`, which sends the App's name
  (lowercase, at most 64 characters) and the host of its homepage, never a path
  or query. A person asks for an App by opening a
  [GitHub issue](https://github.com/ajnart/self-host/issues) instead.
- **Feedback**, only after you see the text and agree (see below).

Each event also carries the self-host version, OS and architecture. Events are
anonymous: PostHog keeps no person profile and no person properties. GeoIP is
disabled; payloads contain no IP addresses or locations. Receiving network
infrastructure still sees the source IP. Server-side "Discard client IP data"
is a maintainer-controlled setting, not something the CLI verifies.

## Website

self-host.fyi (the site, the docs and Docker Compose Maker at `/compose`) sends
a few anonymous usage events to the same EU PostHog proxy as the CLI. It sets no
cookie and stores nothing in your browser for analytics (Docker Compose Maker
keeps only your own settings and selection in local storage), builds no person profile, records no
sessions, and sends nothing when your browser asks not to be tracked. It runs
only on `self-host.fyi`: a local copy of the site, a preview or the
`ghcr.io/ajnart/dcm` image sends nothing. This is separate from the CLI
Telemetry above, and `SELF_HOST_NO_TELEMETRY` does not control it.

Every page you see sends `$pageview`; a page your browser only prerenders sends it once you open it. PostHog's browser library adds properties to every
event: the page URL, referrer and path (query string and fragment removed before
sending), browser name and version, OS, device type, viewport and screen size,
time zone, language and library version. The request also reaches the proxy
with your IP address, as any request does; the site does not rely on a
server-side IP setting. The named events carry Catalog or Container ids, counts
and fixed values only:

| Event                         | Sent when                                                   | Properties                          |
| ----------------------------- | ----------------------------------------------------------- | ----------------------------------- |
| `install_command_copied`      | you copy the install command on the home or 404 page        | `method` (`curl`, `wget`, ...)      |
| `app_install_copied`          | you copy `self-host install <app>` on an App page           | `app`                               |
| `recipe_install_copied`       | you copy a Recipe's install command on an App page          | `recipe`                            |
| `share_link_copied`           | you copy the share link of the home page selection          | `count`                             |
| `dcm_mode_changed`            | you switch between the self-host and docker compose pages   | `mode` (`self-host` or `compose`)   |
| `dcm_item_selected`           | you select a container                                      | `id`, `source` (`self-host`, `dcm`) |
| `dcm_item_unselected`         | you unselect a container                                    | `id`, `source`                      |
| `dcm_compose_copied`          | you copy the Compose file or the `.env`                     | `count`, `ids`, `file`              |
| `dcm_compose_downloaded`      | you download the Compose file or the `.env`                 | `count`, `ids`, `file`              |
| `dcm_share_copied`            | you copy the share link of your selection                   | `count`                             |
| `dcm_selfhost_command_copied` | you copy the `self-host install` command                    | `count`, `ids`                      |
| `dcm_template_opened`         | you open a Template page                                    | `id`                                |
| `dcm_template_copied`         | you copy a Template's Compose file or `.env`                | `id`                                |
| `dcm_search_opened`           | you open the search dialog                                  | none                                |
| `dcm_settings_opened`         | you open the settings panel                                 | none                                |
| `dcm_suggest_opened`          | you open the Suggest container page                         | none                                |
| `dcm_suggest_prompt_copied`   | you copy the agent prompt on the Suggest container page     | none                                |
| `dcm_suggest_issue_opened`    | you open the issue template from the Suggest container page | none                                |

`file` is `compose` or `env`. Never sent: what you type, the search
query, query strings and fragments, Compose or `.env` content, settings values
and the app name and repository you type on the Suggest container page. See [ADR 0013](https://github.com/ajnart/self-host/blob/main/docs/adr/0013-website-analytics.md).

## What is never sent automatically

Host names, absolute file paths, typed inputs, secrets, App data, raw error or
panic text, IP addresses or locations. Stack files are relative to the Go
module, never to the machine where the binary was built or installed.

## There is no stored ID

Nothing identifies you or your machine, and nothing is saved. Each run uses a
random value held in memory and thrown away when the command ends, so one run
cannot be linked to another.

## Notice and controls

Onboarding's Welcome step mentions Telemetry and links here, with no button or
toggle. Commands print nothing about it, and nothing records that the notice
was shown. Usage and logs wait at most 500 ms and are dropped silently if the
network is slow, without retries.

To turn all Telemetry and Feedback off, set either environment variable:

```sh
export SELF_HOST_NO_TELEMETRY=1
```

or `DO_NOT_TRACK=1`. Set to 1 (or true); any value except empty, 0 or false turns it off. Sending is always off when `CI` is set or the binary is a
development build. Tests use fake transports and never send real Telemetry.

## Feedback is deliberate

When an agent cannot fix a problem, `self-host feedback --message "…"` can send
a report after you see the exact text and agree. `--yes` is only for approval
already given in chat. Feedback is the one event carrying approved free text;
the agent must remove personal details and the CLI masks known secrets again.
`--app <id>` adds a short Debug report summary, never App logs.

Messages from `--message` or stdin are limited to 4096 bytes. Approved Feedback
uses the same endpoint, anonymity and off switches, but waits up to five seconds
for delivery and reports failure. With Telemetry off it sends nothing, exits 1,
and points to [GitHub Issues](https://github.com/ajnart/self-host/issues).

## Technical sources

- [PostHog Go library](https://posthog.com/docs/libraries/go).
- [PostHog OTLP/HTTP logs endpoint and project-token authentication](https://posthog.com/docs/logs/installation/other).
- [PostHog reverse proxies](https://posthog.com/docs/advanced/proxy).

Logs use the proxy's documented `/i/v1/logs` path with a bearer project token.
Fake-transport tests verify the requests, not live proxy ingestion or server-side
IP discard. The key embedded in releases is a public write-only project token,
not a personal API key.