Skip to content

fix(telemetry): default telemetry to opt-out with explicit consent UI - #1069

Open
edelauna wants to merge 4 commits into
mainfrom
issue/830-1
Open

fix(telemetry): default telemetry to opt-out with explicit consent UI#1069
edelauna wants to merge 4 commits into
mainfrom
issue/830-1

Conversation

@edelauna

@edelauna edelauna commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Related GitHub Issue

Refs: #830 (consent/privacy half only — Part A, event volume, is separate work in #835)

Description

Splits the consent and privacy fixes out of #835 into their own PR, so they can ship independent of the telemetry event-volume work in that PR.

Consent default. The banner used to send telemetrySetting: "enabled" when a user dismissed it with the close button, with no way to decline. This PR changes the semantics to a disclosed opt-out default: "unset" (no choice made) and "enabled" both keep telemetry on; only an explicit "disabled" turns it off. The banner's close button now sends no message at all, so dismissing it leaves the default in effect instead of recording an affirmative choice. isTelemetryOptedIn() in packages/types/src/telemetry.ts is the single source of truth for this logic — used by the banner, the About settings checkbox, and both the extension-host and webview PostHog clients.

Explicit consent UI. TelemetryBanner.tsx gets separate Accept and Decline actions instead of only a close button.

Live VS Code telemetry gating. extension.ts now listens to vscode.env.onDidChangeTelemetryEnabled and re-evaluates telemetry state immediately when the user flips VS Code's global telemetry toggle, ANDing it with the stored telemetrySetting. webviewMessageHandler.ts does the same for the webview's own PostHog client, and serializes concurrent telemetrySetting messages through a queue so a fast toggle can't have an earlier, slower write clobber a later one.

Docs and strings. PRIVACY.md now discloses the opt-out default and that the "does not collect code or prompts" claim applies to the PostHog path specifically. Banner and settings copy updated in all locales.

Visual regression coverage. Added a Playwright CT snapshot for TelemetryBanner (first visual test to exercise VSCodeButton) and fixed the CT harness's button mock, which rendered as a bare unstyled <button> with no VS Code styling — screenshots would have shown that instead of the real look. Styled button[appearance] in the CT-only theme CSS using the existing --vscode-button-* tokens; this fixes appearance for any future visual test using VSCodeButton, not just this one.

Explicitly out of scope (left for #835 or a follow-up): the circuit breaker for CODE_INDEX_ERROR retry storms, Task Completed aggregation of toolsUsed/messageCount, telemetry shutdown draining, and the modelCache.ts empty-response throttle. None of those files are touched here.

Test Procedure

  • pnpm check-types passes repo-wide.
  • 109 unit/integration tests pass across @roo-code/types, src, and webview-ui — the exact files touched (telemetry consent logic, banner, settings checkbox, extension activation/deactivation, webview message handling).
  • Lint clean on every touched file; src/eslint-suppressions.json only lost the now-stale __tests__/extension.spec.ts entry, no new suppressions added.
  • pnpm test:visual:docker passes deterministically for all 3 visual tests (2 pre-existing + the new TelemetryBanner baseline).
  • No changesets added, per this PR's scope guidance.

Pre-Submission Checklist

  • Issue Linked: This PR is linked to an approved GitHub Issue (see "Related GitHub Issue" above).
  • Scope: My changes are focused on the linked issue (one major feature/fix per PR).
  • Self-Review: I have performed a thorough self-review of my code.
  • Testing: New and/or updated tests have been added to cover my changes (if applicable).
  • Visual Snapshot (UI changes only): If a user would notice this change at a glance (layout, theme tokens, brand elements, empty/error states), I've added or updated a *.visual.tsx snapshot in webview-ui/. See webview-ui/AGENTS.md → "When a UI change needs a snapshot".
  • Documentation Impact: I have considered if my changes require documentation updates (see "Documentation Updates" section below).
  • Contribution Guidelines: I have read and agree to the Contributor Guidelines.

Visual Snapshots

Added webview-ui/src/components/common/__tests__/TelemetryBanner.visual.tsx with baseline __screenshots__/telemetry-banner-dark.png, showing the banner with its explicit Accept (primary) and Decline (secondary) buttons.

Documentation Updates

  • Yes, documentation updates are required. PRIVACY.md updated in this PR to disclose the opt-out default and clarify PostHog-specific scope.

Additional Notes

Split out of #835 per review — that PR mixed event-volume reduction with consent/privacy fixes across ~65 files. This PR contains only the consent/privacy hunks, branched clean from main.

Summary by CodeRabbit

  • New Features

    • Added clear Accept and Decline options for telemetry, while dismissing the notice without changing settings.
    • Telemetry now respects both the extension preference and VS Code’s global telemetry setting.
    • Settings and webview state stay synchronized when telemetry preferences change.
  • Documentation

    • Updated privacy disclosures in supported languages to identify PostHog-based, installation-linked usage and error data, clarify retention, and confirm that code and prompts are not collected.
  • Bug Fixes

    • Improved telemetry startup and shutdown reliability, including protection against conflicting preference updates.

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 58bfff8e-082d-4be1-9379-5f50dd03690e

📥 Commits

Reviewing files that changed from the base of the PR and between 2375591 and 0eb3b62.

📒 Files selected for processing (7)
  • codecov.yml
  • src/core/webview/__tests__/webviewMessageHandler.spec.ts
  • src/core/webview/webviewMessageHandler.ts
  • webview-ui/src/components/chat/__tests__/ChatView.scroll-debug-repro.spec.tsx
  • webview-ui/src/components/common/__tests__/TelemetryBanner.visual.fixture.tsx
  • webview-ui/src/components/common/__tests__/TelemetryBanner.visual.i18n.ts
  • webview-ui/src/components/common/__tests__/TelemetryBanner.visual.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/core/webview/webviewMessageHandler.ts
  • webview-ui/src/components/common/tests/TelemetryBanner.visual.tsx

📝 Walkthrough

Walkthrough

The PR centralizes telemetry opt-in logic, gates telemetry with VS Code’s global setting, serializes webview updates, adds explicit consent actions, propagates telemetry state, updates tests, and revises privacy disclosures and translations.

Changes

Telemetry control flow

Layer / File(s) Summary
Shared telemetry contract
packages/types/src/telemetry.ts, packages/types/src/vscode-extension-host.ts, webview-ui/src/utils/TelemetryClient.ts
Adds isTelemetryOptedIn, extends extension state with vscodeTelemetryEnabled, and gates telemetry initialization on both settings.
Extension synchronization
src/extension.ts, src/core/webview/ClineProvider.ts, src/__tests__/extension.spec.ts
Synchronizes stored telemetry settings with VS Code’s live telemetry toggle, updates webview state, and awaits telemetry shutdown during deactivation.
Webview update ordering
src/core/webview/webviewMessageHandler.ts, webview-ui/src/App.tsx, src/core/webview/__tests__/*, webview-ui/src/__tests__/TelemetryClient.spec.ts
Queues launch and setting updates, applies the global VS Code telemetry gate, and tests concurrent update and initialization races.
Consent UI and validation
webview-ui/src/components/common/*, webview-ui/src/components/settings/*, webview-ui/playwright/*
Adds explicit Accept and Decline actions, keeps close dismissal neutral, and adds unit and visual coverage.
Privacy and localized disclosures
PRIVACY.md, webview-ui/src/i18n/locales/*
Identifies PostHog, clarifies retention and installation-linked identifiers, and updates telemetry consent wording in supported locales.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

  • Zoo-Code-Org/Zoo-Code#526: Adds the Playwright visual regression infrastructure extended by the telemetry banner visual test.

Suggested labels: awaiting-review

Suggested reviewers: hannesrudolph, taltas

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the telemetry opt-out default and explicit consent UI, which are the main changes.
Description check ✅ Passed The description covers the issue, implementation, testing, scope, visual snapshot, and documentation updates; only minor checklist inconsistencies remain.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue/830-1

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (2)
src/core/webview/__tests__/webviewMessageHandler.spec.ts (1)

1889-1900: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider replacing the fixed microtask-flush count with an explicit signal.

The loop flushes exactly ten microtask turns as a fallback for the fixed code path. This count is a timing heuristic. If webviewDidLaunch later gains another await before it chains onto telemetrySettingQueue, the flush may finish too early and the test would pass or fail for the wrong reason.

The rest of this test already uses deferred-promise handshakes. An explicit signal from the queued update, or awaiting an exported queue handle, would remove the magic number.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/webview/__tests__/webviewMessageHandler.spec.ts` around lines 1889 -
1900, Replace the fixed ten-turn microtask flush in the webviewDidLaunch test
with an explicit deferred-promise or queue-completion signal tied to the queued
telemetry update. Await that signal alongside snapshotTakenPromise so the test
synchronizes with the actual operation rather than relying on timing, preserving
the existing pre-fix snapshot behavior.
webview-ui/src/__tests__/TelemetryClient.spec.ts (1)

107-134: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consolidate TelemetryClient spec coverage into one file.

webview-ui/src/__tests__/TelemetryClient.spec.ts and webview-ui/src/utils/__tests__/TelemetryClient.spec.ts both cover TelemetryClient and updateTelemetryState. Move one set or merge the specs so this coverage does not drift between two files.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@webview-ui/src/__tests__/TelemetryClient.spec.ts` around lines 107 - 134,
Consolidate the duplicate TelemetryClient and updateTelemetryState test coverage
from webview-ui/src/__tests__/TelemetryClient.spec.ts and
webview-ui/src/utils/__tests__/TelemetryClient.spec.ts into a single spec file.
Move or merge the relevant cases, remove the redundant file or duplicated tests,
and preserve coverage for both telemetry-disabled and opted-in initialization
behavior.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@PRIVACY.md`:
- Around line 35-42: Update the Telemetry (Usage Data) section in PRIVACY.md to
state the active PostHog event-retention period or link to the authoritative
retention policy, replacing the vague “only as long as needed” wording. Verify
the stated period against the current PostHog plan or configuration before
merging.

In `@src/core/webview/webviewMessageHandler.ts`:
- Around line 659-666: Guard the queued telemetry update in the webview launch
handler with TelemetryService.hasInstance() before accessing
TelemetryService.instance. Preserve the existing telemetry-setting calculation
and update behavior when an instance exists, while skipping the update when it
does not.

In
`@webview-ui/src/components/common/__tests__/TelemetryBanner.visual.fixture.tsx`:
- Around line 19-20: Update the visual fixture’s i18next initialization so its
init promise is returned and supplied to the test setup, then await that promise
before calling mount for TelemetryBannerFixture. Ensure initialization completes
before Trans renders, without changing the existing translation configuration.

---

Nitpick comments:
In `@src/core/webview/__tests__/webviewMessageHandler.spec.ts`:
- Around line 1889-1900: Replace the fixed ten-turn microtask flush in the
webviewDidLaunch test with an explicit deferred-promise or queue-completion
signal tied to the queued telemetry update. Await that signal alongside
snapshotTakenPromise so the test synchronizes with the actual operation rather
than relying on timing, preserving the existing pre-fix snapshot behavior.

In `@webview-ui/src/__tests__/TelemetryClient.spec.ts`:
- Around line 107-134: Consolidate the duplicate TelemetryClient and
updateTelemetryState test coverage from
webview-ui/src/__tests__/TelemetryClient.spec.ts and
webview-ui/src/utils/__tests__/TelemetryClient.spec.ts into a single spec file.
Move or merge the relevant cases, remove the redundant file or duplicated tests,
and preserve coverage for both telemetry-disabled and opted-in initialization
behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d0452b8c-95db-46c1-a02a-2b4d497d0cca

📥 Commits

Reviewing files that changed from the base of the PR and between cd29243 and 2375591.

⛔ Files ignored due to path filters (1)
  • webview-ui/src/components/common/__tests__/__screenshots__/telemetry-banner-dark.png is excluded by !**/*.png
📒 Files selected for processing (57)
  • PRIVACY.md
  • packages/types/src/__tests__/telemetry.isTelemetryOptedIn.test.ts
  • packages/types/src/telemetry.ts
  • packages/types/src/vscode-extension-host.ts
  • src/__tests__/extension.spec.ts
  • src/core/webview/ClineProvider.ts
  • src/core/webview/__tests__/telemetrySettingsTracking.spec.ts
  • src/core/webview/__tests__/webviewMessageHandler.spec.ts
  • src/core/webview/webviewMessageHandler.ts
  • src/eslint-suppressions.json
  • src/extension.ts
  • webview-ui/playwright/vscode-theme-dark.css
  • webview-ui/src/App.tsx
  • webview-ui/src/__tests__/TelemetryClient.spec.ts
  • webview-ui/src/components/common/TelemetryBanner.tsx
  • webview-ui/src/components/common/__tests__/TelemetryBanner.spec.tsx
  • webview-ui/src/components/common/__tests__/TelemetryBanner.visual.fixture.tsx
  • webview-ui/src/components/common/__tests__/TelemetryBanner.visual.tsx
  • webview-ui/src/components/settings/About.tsx
  • webview-ui/src/components/settings/__tests__/About.spec.tsx
  • webview-ui/src/i18n/locales/ca/settings.json
  • webview-ui/src/i18n/locales/ca/welcome.json
  • webview-ui/src/i18n/locales/de/settings.json
  • webview-ui/src/i18n/locales/de/welcome.json
  • webview-ui/src/i18n/locales/en/settings.json
  • webview-ui/src/i18n/locales/en/welcome.json
  • webview-ui/src/i18n/locales/es/settings.json
  • webview-ui/src/i18n/locales/es/welcome.json
  • webview-ui/src/i18n/locales/fr/settings.json
  • webview-ui/src/i18n/locales/fr/welcome.json
  • webview-ui/src/i18n/locales/hi/settings.json
  • webview-ui/src/i18n/locales/hi/welcome.json
  • webview-ui/src/i18n/locales/id/settings.json
  • webview-ui/src/i18n/locales/id/welcome.json
  • webview-ui/src/i18n/locales/it/settings.json
  • webview-ui/src/i18n/locales/it/welcome.json
  • webview-ui/src/i18n/locales/ja/settings.json
  • webview-ui/src/i18n/locales/ja/welcome.json
  • webview-ui/src/i18n/locales/ko/settings.json
  • webview-ui/src/i18n/locales/ko/welcome.json
  • webview-ui/src/i18n/locales/nl/settings.json
  • webview-ui/src/i18n/locales/nl/welcome.json
  • webview-ui/src/i18n/locales/pl/settings.json
  • webview-ui/src/i18n/locales/pl/welcome.json
  • webview-ui/src/i18n/locales/pt-BR/settings.json
  • webview-ui/src/i18n/locales/pt-BR/welcome.json
  • webview-ui/src/i18n/locales/ru/settings.json
  • webview-ui/src/i18n/locales/ru/welcome.json
  • webview-ui/src/i18n/locales/tr/settings.json
  • webview-ui/src/i18n/locales/tr/welcome.json
  • webview-ui/src/i18n/locales/vi/settings.json
  • webview-ui/src/i18n/locales/vi/welcome.json
  • webview-ui/src/i18n/locales/zh-CN/settings.json
  • webview-ui/src/i18n/locales/zh-CN/welcome.json
  • webview-ui/src/i18n/locales/zh-TW/settings.json
  • webview-ui/src/i18n/locales/zh-TW/welcome.json
  • webview-ui/src/utils/TelemetryClient.ts
💤 Files with no reviewable changes (1)
  • src/eslint-suppressions.json

Comment thread PRIVACY.md
Comment thread src/core/webview/webviewMessageHandler.ts
Comment thread webview-ui/src/components/common/__tests__/TelemetryBanner.visual.fixture.tsx Outdated
@codecov

codecov Bot commented Jul 31, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.90909% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/core/webview/webviewMessageHandler.ts 86.95% 2 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@edelauna
edelauna marked this pull request as ready for review July 31, 2026 13:51
@github-actions github-actions Bot added the awaiting-review PR changes are ready and waiting for maintainer re-review label Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting-review PR changes are ready and waiting for maintainer re-review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant