claude-code-best/docs/CC_Pure_cleanup_plan.md
James Feng 39ba9a56fd feat: pull in Vite build system + complete packages/builtin-tools/
- Add Vite as alternative build (vite.config.ts, scripts/vite-plugin-*)
- Add dab04af7 RSS fix (distRoot, ripgrep path, post-build)
- Pull in packages/builtin-tools/ (+354 files)
- Pull in packages/agent-tools/, mcp-client/, acp-link/, weixin/
- Copy defines.ts from upstream for Vite compatibility
- Update package.json with Vite scripts and deps
2026-06-01 18:18:03 +08:00

6.7 KiB
Raw Blame History

CC_Pure 遥测清理方案

项目claude-code-best (ccb) v2.1.888 → CC_Pure 仓库:https://github.com/GhostDragon124/CC_Pure 审计报告docs/telemetry-cleanup-audit.md


一、背景ccb 里有哪些遥测系统

ccb 是从 Anthropic 官方 Claude Code 反编译还原的项目。源码中包含 6 个遥测系统:

# 系统 数据流向 默认状态
1 Datadog 日志 api.datadoghq.com ccb 已清空端点/Token默认禁用
2 Sentry 错误上报 sentry.io ccb 未配置 DSN默认 no-op
3 OpenTelemetry 用户自配 OTLP 端点 需显式设 CLAUDE_CODE_ENABLE_TELEMETRY=1
4 1P Event Logging api.anthropic.com/api/event_logging/batch 🔴 默认启用
5 GrowthBook 远程配置 api.anthropic.com/ 🔴 默认启用
6 BigQuery Metrics api.anthropic.com/api/claude_code/metrics 🔴 默认启用

实测验证strace 网络抓包)

测试strace -f -e trace=network ccb --print -p "hello"
环境变量 api.anthropic.com 连接数
无防护 1 次
DISABLE_TELEMETRY=1 1 次(未完全阻断!)
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 0 次

结论:CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 是唯一能完全阻断的配置


二、清理方案纵深防御4 层)

核心思路:环境变量做入口防御 + 源码级切断关键初始化路径,不做"自欺欺人"式的 return true

第 1 层ccb wrapper配置防御

文件~/.local/bin/ccb

#!/bin/bash
export PATH="$HOME/.bun/bin:$PATH"
# CC_Pure: 防御层 — 阻断所有非必要网络流量(遥测、自动更新等)
export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1
exec bun /home/spark/workspace/claude-code-best/dist/cli.js "$@"

原理:该环境变量触发 privacyLevel = 'essential-traffic',使:

  • isTelemetryDisabled()true
  • isAnalyticsDisabled()true(因为 isTelemetryDisabled() 为 true
  • 从而 Datadog、1P Event Logging、BigQuery Metrics 全部失效

第 2 层init.ts — 切断启动时遥测初始化

文件src/entrypoints/init.ts

改动 A(约 L95-106注释掉 GrowthBook + 1P Event Logging 的动态 import 和初始化:

// 改前:
void Promise.all([
  import('../services/analytics/firstPartyEventLogger.js'),
  import('../services/analytics/growthbook.js'),
]).then(([fp, gb]) => {
  fp.initialize1PEventLogging()
  gb.onGrowthBookRefresh(() => {
    void fp.reinitialize1PEventLoggingIfConfigChanged()
  })
})

// 改后:
// CC_Pure: GrowthBook + 1P Event Logging 已永久禁用
// (原代码保留以供参考)
// void Promise.all([...]).then(...)

原因:即使 isAnalyticsDisabled() 返回 true这段代码仍会加载模块并连接 GrowthBook。实测中 DISABLE_TELEMETRY=1 下仍有 1 次 api.anthropic.com 连接,很可能就是这一段绕过的。

改动 BL292doInitializeTelemetry() 函数体开头加 early return

// 改前:
async function doInitializeTelemetry(): Promise<void> {
  if (telemetryInitialized) { return }
  telemetryInitialized = true
  try { await setMeterState() } catch ...

// 改后:
async function doInitializeTelemetry(): Promise<void> {
  // CC_Pure: 遥测已完全禁用
  return;
  // ... 原代码保留

原因setMeterState() 会动态 import ~400KB 的 OpenTelemetry SDK即使最终不导出数据也不该加载。

第 3 层sinks.ts — 不挂载遥测事件管道

文件src/utils/sinks.ts

// 改前:
export function initSinks(): void {
  initializeErrorLogSink()
  initializeAnalyticsSink()   // ← 挂载遥测管道
}

// 改后:
export function initSinks(): void {
  initializeErrorLogSink()
  // CC_Pure: Analytics sink 已永久禁用
  // initializeAnalyticsSink()
}

原因initializeAnalyticsSink() 会把所有 logEvent("tengu_xxx") 调用路由到 Datadog + 1P Event Logging。注释掉后所有 logEvent() 调用变成空操作(事件排队但永不 flush

注意:initializeErrorLogSink() 保留——它只写本地错误日志,不涉及网络。

第 4 层main.tsx — 不初始化 Analytics Gate

文件src/main.tsx L691

// 改前:
void initializeAnalyticsGates();

// 改后:
// CC_Pure: Analytics gate 初始化已永久禁用
// void initializeAnalyticsGates();

原因initializeAnalyticsGates() 调用 GrowthBook 的 checkStatsigFeatureGate_CACHED_MAY_BE_STALE(),会读取本地缓存的远程配置。虽然第 2 层已切断 GrowthBook 的初始化,但为防御纵深也注释掉。


三、不改的文件及原因

src/services/analytics/config.ts — 不修改

该文件保持原样isAnalyticsDisabled() 仍为条件判断:

export function isAnalyticsDisabled(): boolean {
  return (
    process.env.NODE_ENV === 'test' ||
    isEnvTruthy(process.env.CLAUDE_CODE_USE_BEDROCK) ||
    isEnvTruthy(process.env.CLAUDE_CODE_USE_VERTEX) ||
    isEnvTruthy(process.env.CLAUDE_CODE_USE_FOUNDRY) ||
    isTelemetryDisabled()
  )
}

不做 return true 硬编码。原因:

  1. 第 1 层(环境变量)已经让它在正常运行时返回 true
  2. 硬编码 return true 是"自欺欺人"——改返回值但不改调用逻辑
  3. 保留原逻辑可以让后续维护者理解原始设计意图

其他不修改的文件

  • src/services/analytics/growthbook.ts — 1256 行,初始化入口已在 init.ts 切断
  • src/services/analytics/firstPartyEventLogger.ts — 449 行,同上
  • src/utils/telemetry/* — 初始化入口已在 init.ts 切断
  • package.jsonbuild.tstsconfig.json — 完全不碰
  • 所有功能代码工具、API、UI、Bridge、Daemon — 完全不碰

四、改动汇总

文件 改动行数 类型
~/.local/bin/ccb +1 行 配置(环境变量)
src/entrypoints/init.ts ~20 行注释 源码(切断初始化)
src/utils/sinks.ts 1 行注释 源码(切断管道)
src/main.tsx 1 行注释 源码(切断门控)
src/services/analytics/config.ts 不修改

总计3 个源文件4 处注释级改动。


五、验证方法

# strace 网络抓包
strace -f -e trace=network -o /tmp/ccb_test.log \
  ccb --print --dangerously-skip-permissions -p "say hello" 2>&1

# 检查是否有 api.anthropic.com 连接
grep "api.anthropic" /tmp/ccb_test.log
# 期望输出:(空)— 零连接