From 69afdc03b912c21de206fb3e531523f64e92cbc0 Mon Sep 17 00:00:00 2001 From: Rhys Sullivan <39114868+RhysSullivan@users.noreply.github.com> Date: Mon, 24 Aug 2026 19:54:49 -0700 Subject: [PATCH] Disable telemetry in terminal E2E sessions --- e2e/local/cli-telemetry-optout.test.ts | 27 ++++++++++++++++++++++++++ e2e/src/surfaces/cli.ts | 11 ++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 e2e/local/cli-telemetry-optout.test.ts diff --git a/e2e/local/cli-telemetry-optout.test.ts b/e2e/local/cli-telemetry-optout.test.ts new file mode 100644 index 0000000000..441d735f53 --- /dev/null +++ b/e2e/local/cli-telemetry-optout.test.ts @@ -0,0 +1,27 @@ +import { expect, it } from "@effect/vitest"; +import { Effect } from "effect"; + +import { makeCliSurface } from "../src/surfaces/cli"; + +it.live("terminal E2E sessions force product telemetry off", () => + makeCliSurface() + .session( + [ + process.execPath, + "-e", + "console.log([process.env.DO_NOT_TRACK, process.env.EXECUTOR_DISABLE_ANALYTICS, process.env.EXECUTOR_DISABLE_INTEGRATIONS_FETCH].join('|'))", + ], + (terminal) => + terminal.screen + .waitUntil((screen) => screen.text.includes("1|1|1"), { timeoutMs: 5_000 }) + .then((screen) => expect(screen.text).toContain("1|1|1")), + { + env: { + DO_NOT_TRACK: "0", + EXECUTOR_DISABLE_ANALYTICS: "0", + EXECUTOR_DISABLE_INTEGRATIONS_FETCH: "0", + }, + }, + ) + .pipe(Effect.timeout("10 seconds")), +); diff --git a/e2e/src/surfaces/cli.ts b/e2e/src/surfaces/cli.ts index ac71618837..85c0a93250 100644 --- a/e2e/src/surfaces/cli.ts +++ b/e2e/src/surfaces/cli.ts @@ -32,6 +32,15 @@ interface AsciicastEvent { bytes?: number[]; } +// E2E subprocesses must never report product usage or fetch the production +// integrations catalog. Keep these after caller-provided values below so a +// scenario cannot accidentally turn outbound telemetry back on. +const E2E_OUTBOUND_OPT_OUT = { + DO_NOT_TRACK: "1", + EXECUTOR_DISABLE_ANALYTICS: "1", + EXECUTOR_DISABLE_INTEGRATIONS_FETCH: "1", +} as const; + /** terminal-control's JSONL recording → asciicast v2 (what asciinema plays). */ const toAsciicast = (recording: Uint8Array): string => { const events = new TextDecoder() @@ -74,7 +83,7 @@ export const makeCliSurface = (): CliSurface => ({ const session: Session = await tc.launch({ command, cwd: options?.cwd, - env: options?.env, + env: { ...options?.env, ...E2E_OUTBOUND_OPT_OUT }, record: options?.record ? true : undefined, viewport: options?.viewport, });