[STG-2445] feat(cli): classify execution environment in telemetry#2293
Open
shrey150 wants to merge 2 commits into
Open
[STG-2445] feat(cli): classify execution environment in telemetry#2293shrey150 wants to merge 2 commits into
shrey150 wants to merge 2 commits into
Conversation
Add is_container, is_tty, and runtime_provider to anonymous CLI telemetry so events segment by where the CLI runs (container / sandbox / interactive) at the source, instead of fragile behavioral fingerprinting. runtime_provider is derived from std-env plus an env-var allowlist for agent sandboxes (e2b, modal, daytona, codespaces, gitpod, replit). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: 82a8f0c The changes in this PR will be included in the next version bump. This PR includes changesets to release 0 packagesWhen changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Contributor
There was a problem hiding this comment.
1 issue found across 6 files
Confidence score: 3/5
- In
packages/cli/src/lib/telemetry.ts,classifyEnvironmentstill runs when telemetry is opted out, which can collect new environment signals despite user intent and create privacy/compliance risk if merged as-is — gateclassifyEnvironmentbehindtelemetryEnabledbefore merging.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="packages/cli/src/lib/telemetry.ts">
<violation number="1" location="packages/cli/src/lib/telemetry.ts:175">
P2: Opted-out telemetry still classifies the execution environment. Gate classifyEnvironment behind telemetryEnabled so disabled telemetry does not collect new environment signals at all.</violation>
</file>
Architecture diagram
sequenceDiagram
participant CLI as CLI Command
participant Telemetry as TelemetryService
participant Classifier as EnvironmentClassifier
participant StdEnv as std-env
participant FS as FileSystem
participant Env as ProcessEnv
Note over CLI,Telemetry: CLI Anonymous Telemetry Flow (NEW: environment classification)
CLI->>Telemetry: invoke command → create telemetry
Telemetry->>Telemetry: build baseProperties
Telemetry->>Classifier: classifyEnvironment(env) [NEW]
Classifier->>Classifier: check memoized cache
alt First call (cache miss)
Classifier->>FS: detectContainer(): existsSync("/.dockerenv")
FS-->>Classifier: false (typical host)
Classifier->>FS: detectContainer(): existsSync("/run/.containerenv")
FS-->>Classifier: false
Classifier->>StdEnv: hasTTY
StdEnv-->>Classifier: false (piped/CI)
Classifier->>StdEnv: provider
alt StdEnv provider exists (e.g., GITHUB_ACTIONS)
StdEnv-->>Classifier: "github_actions"
else No std-env provider
Classifier->>Env: iterate sandbox vars [E2B_SANDBOX, MODAL_SANDBOX_ID, ...]
alt Sandbox var found
Env-->>Classifier: "e2b" (e.g., E2B_SANDBOX=true)
else No match
Env-->>Classifier: "unknown"
end
end
Classifier->>Classifier: memoize result
end
Classifier-->>Telemetry: { is_container, is_tty, runtime_provider }
Telemetry->>Telemetry: spread into baseProperties
Note over Telemetry: All subsequent cli.* events carry these properties
Telemetry-->>CLI: telemetry ready (events sent to PostHog)
Note over CLI,Env: Unchanged: CI suppression remains, no is_ci property
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Skip classifyEnvironment() filesystem checks when telemetry is opted out, matching the existing gating of install-id and agent detection in createCliTelemetry. No behavior change for enabled telemetry; opted-out users already send zero events. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
STG-2445
What & why
The CLI's anonymous telemetry can't be segmented by where it runs, so "real user" metrics are reconstructed each window via fragile behavioral fingerprinting (one-day + linux + node-version) that drifts. This adds self-reported execution-environment properties so events segment at the source (human vs CI vs container vs sandbox).
Changes
packages/cli/src/lib/environment.ts—classifyEnvironment()→{ is_container, is_tty, runtime_provider }, memoized (env is static per process), mirrorsagent.ts.is_tty←std-envhasTTY;is_container←/.dockerenv//run/.containerenv;runtime_provider←std-envprovider, else an env-var allowlist for agent sandboxes (E2B_SANDBOX→e2b,MODAL_SANDBOX_ID/MODAL_TASK_ID→modal,DAYTONA_SANDBOX_ID→daytona,CODESPACES,GITPOD_WORKSPACE_ID,REPL_ID), elseunknown.telemetry.ts— spreadclassifyEnvironment(env)intobasePropertiesso the props ride everycli.*event.TelemetryPropertiesalready allows the types — no schema change.std-env(only new dep; tier-1, runs fromnode_modules).tests/cli-telemetry.test.ts) + changeset (browse: patch).Purely additive — no change to what is collected: CI suppression is untouched and there is intentionally no
is_ci(CI events are already suppressed; see notes). The rollup (environment_type) is derived downstream in PostHog, not shipped.E2E Test Matrix
pnpm --filter browse test(vitest)pnpm --filter browse lint+tsc --noEmit{is_container:false, is_tty:false, runtime_provider:"unknown"}E2B_SANDBOX=true→ builtclassifyEnvironment()runtime_provider:"e2b"CODESPACES=true→ builtclassifyEnvironment()runtime_provider:"codespaces"is_tty=falsein all;/.dockerenv→is_container=true(Docker, Daytona); E2B/Modal microVMs have no/.dockerenv→ resolved via env var; egress to PostHog reached from sandboxesNotes
isTelemetryDisabled→isCiEnvironment), sois_ciwould be ~always-false in the data; this PR deliberately omits it. "Tag-and-keep CI" (stop suppressing, addis_ci) is a separate, deliberate collection-scope decision.DAYTONA_SANDBOX_IDis observed live but undocumented (best-effort).🤖 Generated with Claude Code
Summary by cubic
Tag anonymous CLI telemetry with execution-environment properties so events can be segmented by where the CLI runs (container, sandbox, interactive). Addresses STG-2445 by removing fragile behavior-based fingerprinting; classification only runs when telemetry is enabled.
New Features
classifyEnvironment()inpackages/cli/src/lib/environment.tsreturningis_container,is_tty, andruntime_provider(memoized per process).telemetry.tsbase properties; gated bytelemetryEnabledto avoid filesystem checks when opted out; no schema change.std-envhasTTY; container via/.dockerenvor/run/.containerenv; provider fromstd-envprovideror sandbox env vars (E2B_SANDBOX,MODAL_SANDBOX_ID/MODAL_TASK_ID,DAYTONA_SANDBOX_ID,CODESPACES,GITPOD_WORKSPACE_ID,REPL_ID).Dependencies
std-env^4.1.0.Written for commit 82a8f0c. Summary will update on new commits.