CLI telemetry
The evlog CLI records one anonymous wide event per run, so we know which commands people use and which ones error. It is the same telemetry toolkit evlog ships for your own CLIs, pointed at itself.
What init records
evlog init asks more questions than the other commands, so it records the answers — which lets the flow lead with the options people actually pick and drop the ones nobody does.
| Recorded | Example |
|---|---|
| Framework, development sink, sampling preset | nuxt, fs, balanced |
| One flag per destination, extra and enricher chosen | initProdAxiom: true |
| Counts | files written, manual steps left, doctor failures |
| Whether an offer had anything behind it | initHadRepeatedErrors: true |
Every string is an id from the CLI's own catalog and is checked against an allowlist before it is sent — an undeclared value is dropped rather than transmitted. Your service name is never recorded, nor package names, paths, or anything read out of your source. The last row says only whether the scan found something, never what it found.
What map records
evlog map records the shape of a scan: the score and its grade, how many entry points there were and how many are instrumented, partial, dark or exempt, which framework was detected, and whether a --min-score or --baseline gate failed the run.
| Recorded | Example |
|---|---|
| Score and grade | mapScore: 72, mapGrade: good |
| Entry point counts by coverage | mapEntryPoints: 34, mapDark: 9 |
| Per kind: entry points and dark entry points | mapKindPage: 12, mapDarkPage: 3 |
| Per sensitivity: money / auth / PII entry points, and dark | mapSensitiveMoney: 2, mapDarkMoney: 1 |
| Per rule: how many entry points failed it, how many waived it | mapFailWideEvent: 6, mapSuppressedWideEvent: 2 |
| Which gate ran, and whether it failed | mapGate: baseline, mapGateFailed: true |
| Where this run sits in the local sequence, and how the score moved | mapRunOrdinal: 7, mapScoreDelta: +4 |
Rule ids are the CLI's own closed set and are already public. Everything read out of your source is a count: no route path, no file name, no project name, no snippet.
mapRunOrdinal and mapScoreDelta answer the question the snapshot cannot: whether running evlog map repeatedly actually makes scores rise. The ordinal is a monotonic counter stored in the CLI's own data directory, and the delta is the signed score change against the previous run on that machine. Absent on the first run.
The counter is per machine, not per project. It is keyed by nothing that identifies the project: no git remote hash, no path. Someone running map across three repos produces one interleaved sequence, which is noisier but the only way to get a per-project trajectory without identifying the project. mapScoreDelta is therefore "since the last map run on this machine", and is only meaningful in aggregate. Both are numbers, so they need no allowlist. The counter resets when evlog telemetry disable purges data, is never written while telemetry is off, and is omitted in ephemeral CI alongside the machine id. There, the ordinal is meaningless and would be a permanent 1.
Kinds are the CLI's own closed set too, and a kind absent from the project is omitted rather than sent as zero, the same convention as a flag left at its default. The dark count for a kind that is present but fully covered is 0, so mapKindPage: 12, mapDarkPage: 3 always reads as "12 pages, 3 dark", never as a missing number. Sensitivity is a heuristic classification (imports and path terms, see the report's $ / A / o markers), so the per-sensitivity counts are an estimate of what the classifier found, not ground truth.
See what is collected
evlog telemetry status
The command prints whether telemetry is on, where its data directory is, and the full disclosure table — every field, its type, and what it is for. The disclosure is generated from the code that sends the event, so it cannot drift from what actually goes over the wire.
Telemetry: enabled (preference: enabled)
Data directory: ~/.config/evlog-cli/telemetry
What is in an event
One event per run, with the command name, how long it took, whether it succeeded, and the error code when it did not. Alongside that: the Node version, the OS and architecture, whether the run was in CI and on which provider, whether stdout is a TTY, and whether an AI coding agent was driving it.
Flags are recorded as the ones you actually passed. Booleans and numbers keep their value; a string value is recorded as <set> rather than by content, unless the flag is explicitly allowlisted. Positional arguments are never recorded at all, and a flag left at its default is not recorded either — evlog map on its own sends an empty flags object. The machine id is a hash, and it is omitted entirely in ephemeral CI.
Turn it off
Any one of these is enough:
# persisted preference
evlog telemetry disable
# per-run, or in a shell profile
EVLOG_TELEMETRY=0 evlog map
# the cross-tool standard, respected everywhere
export DO_NOT_TRACK=1
evlog telemetry disable also purges anything that had been queued and not yet delivered, and resets the map run counter. evlog telemetry enable turns it back on.
Inspect before trusting
To see exactly what a run would send, without sending it:
EVLOG_TELEMETRY_DEBUG=1 evlog map
The would-be payload is printed to stderr.
Commands
| Command | What it does |
|---|---|
evlog telemetry status | Current state, data directory, and the full disclosure |
evlog telemetry enable | Enable anonymous usage telemetry |
evlog telemetry disable | Disable it and purge undelivered data |
doctor
Diagnose an evlog setup — Node version, project resolution, the installed evlog version, the detected framework, and whether local logs are being written.
agents
Teach the AI agents working in your repository how to use evlog — a short block of conventions in AGENTS.md, plus the published agent skills installed through npx skills.