Skip to content

[Fix] Stop code index telemetry storms and hash the machine ID - #2329

Draft
zoomote2[bot] wants to merge 1 commit into
mainfrom
fix/issue-830-telemetry-volume-privacy
Draft

zoomote2[bot] wants to merge 1 commit into
mainfrom
fix/issue-830-telemetry-volume-privacy

Conversation

@zoomote2

@zoomote2 zoomote2 Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

​Created by Roomote. Follow up by mentioning @roomote, in the web UI, or in Discord.

Related GitHub Issue

Closes: #830

Description

Issue #830 covers two goals: lower PostHog event volume and fix consent and privacy gaps. Earlier PRs already shipped most of the issue: task completion aggregation (#1071), model cache empty-response throttling, the consent banner with explicit Accept and Decline (#1069), the vscode.env.isTelemetryEnabled gate with a live toggle listener, and the awaited shutdown (#1070). This PR closes the remaining gaps:

  • A1. Per-workspace circuit breaker in the file watcher. A broken embedder or vector store config re-triggered the failing pipeline on every file-system event. That loop produced the 254,786 Code Index Error events in the June spike. FileWatcher now counts consecutive failed batches. A batch fails when the batch pipeline breaks (deletion or upsert errors) or when every attempted file in the batch fails. After 3 consecutive failures, the watcher drops further events and stops the telemetry until it is recreated. A config change recreates the watcher through CodeIndexManager._recreateServices, so the breaker opens again only when the embedder config actually changes. Isolated per-file failures never trip the breaker. A TelemetryService-level breaker (fix(telemetry): add circuit breaker and shutdown draining to TelemetryService #1070) already caps event volume; this breaker stops the retry loop itself.
  • A3. Remove per-call Tool Used events (regression fix). feat(telemetry): aggregate task completion telemetry with delta installments #1071 moved tool usage into the aggregated toolsUsed breakdown on Task Completed, but fix(telemetry): record tool usage once centrally, sanitize raw tool names #1073 re-added two per-call captureToolUsage calls. Each tool call then sent two events. This PR removes both call sites and the now-dead captureToolUsage and captureConversationMessage methods. recordToolUsage still feeds the per-task breakdown, and a call-site reintroduction now fails typecheck.
  • B2. Salt-hash the PostHog distinct ID. Both PostHog clients used the raw vscode.env.machineId as the distinct ID. A new hashDistinctId helper (SHA-256 with a fixed application salt) now produces the ID in PostHogTelemetryClient. ClineProvider also hashes the value before it posts state to the webview, so the raw machine ID never leaves the extension host. The webview keeps using the posted value as its own PostHog distinct ID, so analytics identity stays stable per device.
  • B3. Privacy policy clarifications. PRIVACY.md now says the machine ID is salted and hashed before it leaves the device, and it states that the Cloud sync pipeline, which transmits task messages when Cloud sync is on, is separate from PostHog telemetry.

The issue references TELEMETRY_GAP_ANALYSIS.md in the repo root. That file does not exist in the repository, so this PR follows the issue body alone.

Test Procedure

  • New unit tests in file-watcher.spec.ts: breaker opens after 3 consecutive failed batches and later events are dropped; a successful batch resets the counter; a batch whose upsert exhausts retries counts as a failure; isolated per-file failures never trip the breaker.
  • PostHogTelemetryClient.test.ts now asserts the PostHog distinct ID equals the salted hash and never contains the raw machine ID.
  • presentAssistantMessage-tool-usage-attribution.spec.ts asserts one recordToolUsage per validated call and no per-call telemetry event.
  • Reviewers can repeat: pnpm --dir src exec vitest run services/code-index core/assistant-message, pnpm --filter @roo-code/telemetry test, then pnpm run check-types and pnpm test.
  • Full validation on this branch: pnpm run check-types passes (11/11 tasks) and pnpm test --force passes (14/14 tasks; 12,572 extension tests, 2,487 webview tests). ESLint suppression counts did not increase.

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 reviewed my own code with care.
  • Writing Style: The PR title and description use Simplified Technical English (ASD-STE100): short sentences, plain words, active voice, one idea per sentence, no contractions.
  • Testing: New and/or updated tests have been added to cover my changes (if applicable).
  • Test Helpers (test changes only): Shared test helpers (src/test-utils/, @/utils/test-utils) are used only for mechanical duplication; test intent and scenario-specific mocks remain visible.
  • Visual Snapshot (UI changes only): If a user would notice this change at a glance (layout, theme tokens, brand elements, empty/error states), I added or updated a *.visual.tsx snapshot in webview-ui/. See webview-ui/AGENTS.md → "When a UI change needs a snapshot". (No UI change in this PR.)
  • Documentation Impact: I checked if my changes need documentation updates (see "Documentation Updates" section below).
  • Contribution Guidelines: I read and agree to the Contributor Guidelines.

Visual Snapshots

No UI change. No snapshot required.

Videos (interaction / animation only)

No interaction change. No video required.

Documentation Updates

  • No documentation updates are required.

Zoo Code Docs needs no paired update. This PR has no user-visible UI or behavior change: the circuit breaker, the event aggregation fix, and the distinct-ID hash are all internal telemetry behavior. The policy text changes live in PRIVACY.md in this repository.

Additional Notes

One operational note for reviewers: PostHog will see a new distinct-ID format after deployment. Existing event history keeps the old IDs, so before-and-after user counts will not join across the deploy boundary.

Get in Touch

0x7777777_

…stinct IDs (#830)

- Add a per-workspace circuit breaker to the code-index file watcher: after
  3 consecutive failed batches it drops further file-system events until the
  watcher is recreated (embedder/vector-store config change), stopping the
  retry loop behind the 254k-event Code Index Error spike.
- Remove the two per-call captureToolUsage sites re-added by #1073 so tool
  usage reports only as the aggregated toolsUsed breakdown on Task
  Completed; drop the dead captureToolUsage/captureConversationMessage
  methods from TelemetryService.
- Salt-hash the PostHog distinct ID (SHA-256 + fixed salt) in
  PostHogTelemetryClient and before posting machineId to the webview, so
  the raw VS Code machine ID never leaves the extension host.
- Update PRIVACY.md: hashed machine-ID wording and a clarification that the
  Cloud sync pipeline is separate from PostHog telemetry (issue #830).
@coderabbitai

coderabbitai Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are limited based on label configuration.

🏷️ Required labels (at least one): 1

  • coderabbit-review-active

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@zoomote2

zoomote2 Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor Author

1 issue outstanding. See session

  • src/services/code-index/processors/file-watcher.ts:536-543 — Circuit breaker opens with no user-visible state change: the code-index UI keeps reporting "Indexed — up-to-date" while every later file event (deletions included) is silently dropped, so the index goes stale for the session without any recovery hint. Consider a dedicated event or a summary flag the orchestrator can turn into an Error/Standby state.

Reviewed fd1399f

@github-actions

github-actions Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Review status

This PR was opened by an automated account. A human maintainer must verify the change intent, provenance, and validation before merging.

Current step: Mark the PR ready. Required CI must pass before CodeRabbit starts.

Review-state labels are managed by this workflow; do not edit them manually. community-approved is managed the same way — do not add or remove it manually. It signals a fresh community code approval for the current head as an advisory priority only; maintainer review is still required.

Comment on lines +536 to +543
if (!this.circuitBreakerOpen && this.consecutiveFailedBatches >= CIRCUIT_BREAKER_BATCH_THRESHOLD) {
this.circuitBreakerOpen = true
this.accumulatedEvents.clear()
console.error(
`[FileWatcher] Circuit breaker opened after ${this.consecutiveFailedBatches} consecutive failed batches; ` +
`dropping further file-system events for this workspace until the embedder or vector store configuration changes.`,
)
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Circuit breaker opens with no user-visible state change.

When the breaker opens here, the only signal is a console.error. On this same trip batch, the orchestrator's onBatchProgressUpdate handler still transitions the state to Indexed ("File changes processed. Index up-to-date.") because the final progress event fires with processedInBatch === totalInBatch, and the orchestrator's onDidFinishBatchProcessing handler only logs summary.batchError — nothing reaches the state manager.

From this point on, every file-system event in the workspace is dropped silently (deletions included), so the index goes permanently stale for the session while the UI keeps claiming it is up-to-date. A user who fixed a transient outage (e.g. an Ollama restart) gets no signal and no recovery hint until they happen to change config or re-run indexing.

Consider surfacing the open breaker to the code-index state — e.g. a dedicated event or an circuitBreakerOpen flag on BatchProcessingSummary that the orchestrator converts into an Error/Standby state message — so the UI stops claiming "up-to-date" once the watcher has stopped consuming events.

@codecov

codecov Bot commented Nov 5, 2026

Copy link
Copy Markdown

Codecov Report

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

Files with missing lines Patch % Lines
src/services/code-index/processors/file-watcher.ts 85.71% 2 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reduce PostHog event volume and fix telemetry consent/privacy gaps

1 participant