fix(telemetry): re-check the config-file opt-out once config is readable
Follow-up to #1294, which merged before this fix landed on its branch. Addresses Kilo's worker.ts:38 finding there: "Worker boot init cannot see a config-file telemetry opt-out".
Problem
#1294 made the TUI server worker call Telemetry.init() at module load, before Instance context exists on that thread. Inside doInit(), Config.get() throws there and was treated as "not disabled", so telemetry came up enabled. Because init() is idempotent, the prompt loop's later call (inside Instance context, where the config is readable) joined the settled promise and never re-read it. A user with telemetry.disabled: true in opencode.json and no env var shipped telemetry for the whole first session.
Fix
doInit()records when the config check could not run (configOptOutUnverified).- The next
Telemetry.init()call re-reads the config once it is readable. If the file opts out, it stops the loop monitor and flush timer and disables telemetry for the rest of that generation;track()then drops events. Once a re-check has read the config,init()is back on the plain idempotent path. - The env var remains the only opt-out honoured before the config is readable, which matches the main thread, where the CLI middleware initialises telemetry before
Instance.provide()for every command. Holding flushes until the config is verified would re-open the frozen-then-killed blind spot #1294 exists to close, so the immediate anchor flush is kept.
Tests
test/altimate/telemetry/first-run-health.test.ts: unreadable-then-disabled (no further fetch, loop monitor stopped), unreadable-then-enabled (stays enabled, config not re-read a third time), readable-and-disabled (existing behaviour).
🤖 Generated with Claude Code
https://claude.ai/code/session_01WrT7MEUL5CYvpjf9cJbeQR
[!NOTE]
Medium Risk
Changes telemetry enable/disable timing and init concurrency guards; incorrect behavior would either leak events or drop legitimate telemetry, but scope is isolated to the altimate telemetry module with strong test coverage.
Overview
Fixes a privacy bug where early Telemetry.init() (TUI worker at module load, before Instance context) could not read opencode.json, started telemetry anyway, and never re-evaluated telemetry.disabled because later init() calls only joined the settled promise.
configOptOutUnverified is set when Config.get() fails during doInit(); the next init() runs recheckConfigOptOut() (memoized via recheckPromise) and, if the file opts out, tears down the flush timer, loop monitor, and App Insights state so track() drops events. A generation token prevents a stale recheck from disabling a new lifecycle after shutdown + re-init; shutdown also clears recheck flags. Failed flushes no longer retry into the buffer once telemetry has been disabled mid-flight.
Adds first-run-health.test.ts coverage for late disable, stay-enabled after verified config, unchanged first-read disable, repeated recheck until readable, and the shutdown race.
Reviewed by Cursor Bugbot for commit 7c7ca1e765f4493551e0069784fc7092a7e7cfa1. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by cubic
Fixes the telemetry config-file opt-out being ignored when the first Telemetry.init() runs before the config is readable (the TUI server worker). Users with telemetry.disabled: true in opencode.json no longer ship telemetry for the whole first session.
Bug Fixes
doInit()now flags when the config check could not run; the nextinit()call re-reads the config once readable and, if it opts out, disables telemetry for the rest of the session.- A pending recheck that finishes after shutdown and re-init is ignored, so it can't clear the new session's telemetry state.
- Failed flushes don't re-buffer events once the config recheck has disabled telemetry.
- The env var remains the only opt-out honored before the config is readable.
- The anchor flush is kept so the frozen-then-killed blind spot from #1294 stays closed.
Summary by CodeRabbit
- Bug Fixes
- Telemetry now correctly honors configuration-based opt-outs when configuration is initially unavailable during startup.
- Telemetry state is reset cleanly across initialization and shutdown cycles.
- Prevented stale configuration checks from affecting later telemetry sessions.
- Events are no longer restored after telemetry is disabled during a failed flush.
- Tests
- Added coverage for delayed configuration checks, retry behavior, session restarts, and disabling telemetry while monitoring is active.