feat: send one final telemetry_opted_out event when telemetry is disabled
Closes #1499
Stacked on #1500 (user id and tenant on events); review this one after it, or read only the last commit.
What
When telemetry is disabled, a machine that has sent telemetry before sends exactly one final telemetry_opted_out event, and then nothing until telemetry is turned back on.
- New
telemetry/opt-out.ts: the marker file~/.altimate/telemetry-opted-outnext to the machine id, and a read of the machine id that never mints one. telemetry/index.ts:recordOptOut(source)runs from both disabled branches of init (envfor the environment variables,configfortelemetry.disabled). It stops at once when the marker exists or no machine id exists, applies the same sink rules as a normal init (test runners never reach the production sink), uses the identity cached by an earlier signed-in run without any request, posts one envelope with a 3 s cap, and writes the marker only once the ingest endpoint accepted it, so an offline launch tries again next time. The event carriesmachine_id,cli_version,opt_out_source, anduser_idandtenantwhen they were cached. A normal init clears the marker.- The event type is declared in the union for documentation; it is never sent through
track().
Why
Telemetry is on by default and can be turned off. An opted-out machine goes silent, which on the dashboards is indistinguishable from a client that stopped emitting, so missing events get investigated as bugs. With the opt-out as the last event, the dashboards can state the opt-out count and attribute the silence that follows. Opt-outs set before the first launch produce no event; the dashboard states that remainder as unknowable.
Verification
bun test test/altimate/telemetry/opt-out.test.ts: 4 tests. The final event and its properties against a stubbed ingest endpoint, with the identity taken from the cache and no request to resolve it; nothing sent afterwards and nothing on a later init; no event and no marker without a machine id; the marker only after a 2xx (a 500 leaves it for the next launch); a normal init removes the marker.- Identity suite (3) and the existing telemetry suites pass;
tsgo --noEmitclean; oxlint and prettier clean on the new files.
Review log (claims and residuals Codex reviews against): https://github.com/AltimateAI/altimate-code/pull/1501#issuecomment-6186949559
š¤ Generated with Claude Code
https://claude.ai/code/session_011AhtJPr3nmT1Po92ZQk4VE
Summary by cubic
Sends one final telemetry_opted_out event when telemetry is disabled, so dashboards can distinguish opted-out machines from clients that stopped emitting. Closes #1499.
- The event carries the machine id, CLI version, opt-out source, and cached user id and tenant; it is sent at most once, guarded by a
telemetry-opted-outmarker file next to the machine id. - The marker is written only after the ingest endpoint accepted the event, so an offline launch retries next time; a normal init clears it, so a later opt-out is recorded again.
- A send still in flight when telemetry is re-enabled is dropped, so it never recreates the marker for the new lifecycle.
- The machine id is read without minting one, so machines that never sent telemetry send nothing; the opt-out path never runs under the force flag or a test runner unless a test opts in.