No-Mistakes Telemetry Privacy Options: Local-Only vs Remote Data
No-mistakes provides granular telemetry controls that keep read-operation metrics in local gate files while allowing optional mutation-event reporting to self-hosted Umami instances, configurable via build-time variables and the NO_MISTAKES_TELEMETRY environment flag.
The kunchenguid/no-mistakes repository implements a privacy-conscious telemetry system that separates read-surface analytics from mutation-surface event tracking. Understanding these no-mistakes telemetry privacy options ensures you can audit exactly what data remains on your local filesystem and what conditionally transmits to remote endpoints.
Understanding the Two Telemetry Surfaces
The telemetry architecture in no-mistakes operates through two distinct surfaces defined in internal/telemetry/telemetry.go. Each surface handles different user interactions with specific privacy implications.
Read-surface telemetry captures lightweight UI metrics from commands like axi status or stats agents. This data includes action counts and timestamps but explicitly excludes raw prompts, diffs, or run IDs. By default, this surface operates in local-only mode, storing deduplication state in a gate file without any network transmission.
Mutation-surface telemetry records high-level lifecycle events such as run started, run finished, and fix operations. No command arguments, file contents, or agent outputs are included in these payloads. Remote transmission only occurs when the binary is compiled with specific host variables, otherwise this surface remains local-only as well.
Local-Only Telemetry Implementation
The Gate File Mechanism
The read-surface telemetry maintains privacy through a local gate file managed by internal/telemetry/readgate.go. This implementation persists state in a JSON file located at the path returned by TelemetryGateFile() in internal/paths/paths.go, typically resolving to <NM_HOME>/telemetry_gate.json.
The gate file serves two critical functions: it deduplicates events to prevent duplicate logging and implements rate-limiting to approximately one write per ten minutes. Because this data never leaves the local machine, read patterns remain entirely private even in the default configuration.
Privacy Guarantees in Read Operations
As implemented in internal/cli/telemetry.go, the read-surface telemetry explicitly sanitizes all data before local storage. The code ensures that no command arguments, prompt text, or file diffs enter the telemetry pipeline. Only anonymized counts and timestamps reach the gate file, making this surface suitable for air-gapped environments without additional configuration.
Remote Data Transmission Controls
Umami Integration for Mutation Events
When enabled, mutation-surface telemetry transmits to a self-hosted Umami analytics server. The client initialization in internal/telemetry/telemetry.go reads compiled-in values from internal/buildinfo/version.go, specifically the variables TelemetryHost and TelemetryWebsiteID.
These build-time values determine the remote destination. If they remain unset during compilation, the Umami client initialization is skipped entirely, forcing local-only operation even for mutation events. Tests in internal/cli/telemetry_test.go and internal/cli/wizard_test.go verify that no network requests occur when these values are absent.
Build-Time Configuration
You can embed custom telemetry endpoints during the build process by exporting environment variables before compilation:
TelemetryHost="https://umami.internal.company.com" \
TelemetryWebsiteID="550e8400-e29b-41d4-a716-446655440000" \
make build
The linker injects these values into buildinfo.TelemetryHost and buildinfo.TelemetryWebsiteID as defined in internal/buildinfo/version.go. A binary built without these variables contains no remote telemetry capability, ensuring all data remains local by default.
Disabling Telemetry at Runtime
Environment Variable Opt-Out
Even when compiled with remote endpoints, you can suppress all telemetry emission at runtime using the NO_MISTAKES_TELEMETRY environment variable. Setting this to 0 (or alternatively using NM_TELEMETRY=off) immediately disables both gate file updates and network transmission:
export NO_MISTAKES_TELEMETRY=0
no-mistakes run --target production
The validation logic in internal/telemetry/config_test.go confirms this behavior through the test TestDefaultDisablesTelemetryWhenEnvIsOff, which asserts that the telemetry client returns a no-op implementation when this variable is present, guaranteeing zero data emission.
Complete Privacy Lockdown
To ensure absolute data privacy, combine build-time and runtime controls. Compile the binary without embedded telemetry hosts, then set the opt-out environment variable:
# Build without remote endpoints
make build
# Runtime enforcement
export NO_MISTAKES_TELEMETRY=0
This configuration ensures that internal/telemetry/telemetry.go initializes neither the Umami client nor the local read gate, creating a completely silent telemetry state.
Verifying Your Privacy Settings
Inspecting Local Gate Data
You can audit exactly what telemetry data remains local by examining the gate file directly:
cat "$(no-mistakes env --print NM_HOME)/telemetry_gate.json"
This JSON contains only event hashes and timestamps, confirming that internal/paths/paths.go correctly isolated the read-surface data to your local filesystem according to the TelemetryGateFile() implementation.
Checking Remote Configuration
To verify whether your binary includes remote endpoints, inspect the build information:
no-mistakes version --telemetry
If this output shows empty TelemetryHost and TelemetryWebsiteID fields, the binary operates in local-only mode regardless of environment variables. The initialization logic in internal/telemetry/telemetry.go requires non-empty host strings before creating any HTTP clients, ensuring no accidental remote connections.
Summary
- Read-surface telemetry remains local-only by default, storing throttled, anonymized metrics in
<NM_HOME>/telemetry_gate.jsonvia the implementation ininternal/telemetry/readgate.go. - Mutation-surface telemetry only transmits to remote Umami instances when
TelemetryHostandTelemetryWebsiteIDare embedded during build viainternal/buildinfo/version.go. - Runtime opt-out is absolute via
NO_MISTAKES_TELEMETRY=0, which forces a no-op telemetry client as verified byTestDefaultDisablesTelemetryWhenEnvIsOffininternal/telemetry/config_test.go. - No sensitive data (prompts, diffs, arguments, or file contents) ever enters the telemetry pipeline according to the sanitization logic in
internal/cli/telemetry.go. - Verification is possible by inspecting the local gate file path returned by
TelemetryGateFile()ininternal/paths/paths.goor checking build-time constants in the binary.
Frequently Asked Questions
What data does no-mistakes collect by default?
By default, no-mistakes collects only high-level interaction counts and timestamps for read operations, stored locally in telemetry_gate.json. No remote data transmission occurs unless the binary was explicitly built with the TelemetryHost and TelemetryWebsiteID variables defined in internal/buildinfo/version.go. Mutation events remain local unless those build-time conditions are met.
How do I completely disable remote telemetry?
Set the environment variable NO_MISTAKES_TELEMETRY=0 before running any command. This forces the telemetry client initialization in internal/telemetry/telemetry.go to return a no-op implementation, preventing both local gate file updates and network requests. For permanent disabling, build the binary without setting the TelemetryHost and TelemetryWebsiteID variables.
Can I use my own telemetry server instead of the default?
Yes. During compilation, export your self-hosted Umami endpoint and website ID:
TelemetryHost="https://umami.mydomain.com" \
TelemetryWebsiteID="my-uuid-here" \
make build
The resulting binary directs all mutation-surface telemetry to your specified instance while maintaining local-only behavior for read-surface data, as controlled by the logic in internal/telemetry/telemetry.go.
Where is the local telemetry data stored?
Local telemetry state persists in a JSON file at the path returned by TelemetryGateFile() in internal/paths/paths.go, typically located at <NM_HOME>/telemetry_gate.json. This file contains only event deduplication hashes and timestamps, with no user content, command history, or repository data ever written to disk.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →