Skip to content

fix(polyfill): serve Statsig XHR and Beacon telemetry guard as a skeleton provider - #56

Open
yorkane wants to merge 5 commits into
RyensX:mainfrom
yorkane:codex/statsig-telemetry
Open

yorkane wants to merge 5 commits into
RyensX:mainfrom
yorkane:codex/statsig-telemetry

Conversation

@yorkane

@yorkane yorkane commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

改动:改为虚拟修改骨架实现(本 PR 已 force-push 重写)

原实现(f986aa4 + 2d8beac)直接在上游文件 codex-bridge-polyfill.js 里给 XMLHttpRequest.prototype 与 navigator.sendBeacon 打猴补丁。按仓库自身的架构约定,这类行为应作为虚拟修改骨架的独立 Provider 提供,上游文件保持零改动。本版按此重写。

判据:codex-bridge-polyfill.js 相对 main 的 diff 为空,并新增测试断言该文件不得再出现 XMLHttpRequest.prototype.open / sendBeacon / 两个旧补丁标记。

实现

  • 新增 Provider web-shell/internal/providers/codex-statsig-telemetry-guard.js:接管 XHR 与 Beacon 两条通道,命中 chatgpt.com 的 /ces/v1/rgstr 与 /ces/v1/log_event 时不发真实请求、本地模拟成功响应;其余 URL 一律透传。
  • 新增修改点 web.runtime.network.telemetry-guard(组 web-network + 适配器 networkRequest),与既有 web.runtime.network.statsig(fetch 通道)、web.runtime.network.telemetry(IPC 通道)并列。XHR/Beacon 是与那两条独立的上报通道,独立成点才能分别观察是否真被吞掉;另外 browser host 对"同一个点被两个 Provider 绑定"有加载期硬校验,复用既有点会直接抛错。
  • 接线共 6 处:BROWSER_PROVIDER_DEFINITIONS 的 Provider 绑定、static-assets.cjs 的 URL 常量 / Provider key 映射 / 静态文件表 / 聚合启动顺序 / 逐文件回退加载列表、en-US 语言包点描述。

保留的关键细节(原 PR 第二个提交修的那个缺陷):XHR 的 status / statusText / response / responseText / readyState 是原型上的只读 IDL getter,直接赋值会被静默忽略,SDK 读到的仍是 readyState=0,因此用 Object.defineProperty 只覆盖实例、不污染原型;测试用带只读 getter 的假 XHR 复现该形状来守住这点。

骨架规范落点:

  • 命中上报只发生在 send / sendBeacon 真正吞掉遥测时,不在 installer 完成时上报(MODIFICATION_SKELETON.md 规定安装完成只代表 ready)。调试页因此反映真实流量:安装后 emits 为 0,透传流量不计数。
  • 通过 modificationScope.own() 登记还原函数,换页时由宿主逆序 dispose,避免旧补丁继续吃掉新页面请求。
  • 脚本不自注册:正文由 wrapBrowserProviderSource 包成 providers.register 调用,测试断言了包装发生、且加载顺序在 tooltip-dismiss 之后、Kernel 激活脚本之前。

配套的必要改动

新增修改点会打破仓库里硬编码的点计数,已一并同步(与主题同属一个原子变更:拆开会让任一提交都无法通过构建):

  • scripts/check-modification-boundaries.cjs 三处点数。该脚本是 build:gateway 的 pretest 环节,不同步则全新构建在编译阶段直接抛错(实测 pnpm run build:gateway 退出码 1)。
  • compatibility-registry / compatibility-service / modification-kernel / modification-equivalence / official-desktop-compat 五个测试文件的点数 103 改 104;modification-kernel 的 host 分布首位 37 改 38、前缀分布首位 37 改 38、web-network 组 3 改 4;compatibility-service 中"基础点加 1 个外部插件点"的合并数改为 105。
  • 新测试文件登记进 package.json 的 test 脚本,否则 pnpm test 不会执行它。

zh-CN 语言包没有新增键:该文件按仓库现状不承载任何 runtimeCompatibility.point.* 文案(中文取 catalog.ts 的中文描述经 metadataText 回退),测试已断言并守住该约定。

验证

独立克隆 + 全新构建下跑 pnpm test:448 tests / 442 pass / 6 fail,build:gateway 退出码 0。6 条失败与基线(f6fd79c 全新构建)逐字相同,均与本改动无关:3 条 official-desktop-compat 是测试机装有官方 ChatGPT Desktop 被扫到 app.asar;static-assets、runtime-compatibility-page、plugin-config 各 1 条是上游 1f07656 改了 i18n 标题与 effort 取值却没同步测试期望。

新增 8 条用例全绿,覆盖:拦截并模拟成功(200 / readyState 4 / responseText 可读 / load 与 loadend 各一次 / 只覆盖实例不污染原型)、相似域名与外域不误拦、Beacon 命中返回 true 且未触达原生、同代次二次加载幂等、own() 的 dispose 还原原型后透传恢复、点只声明一次且绑定一次。

与其他 PR 的关系

本 PR 拦 renderer 侧的 XHR/Beacon 通道。无出口机器上还有一条走 Electron 主进程 net.fetch 的 Statsig 控制面通道,本 Provider 覆盖不到,由 #58 处理;两者互补不冲突。#58 目前基于 #57#57 合并后可 rebase。

@yorkane

yorkane commented Sep 17, 2026

Copy link
Copy Markdown
Contributor Author

补充:本 PR 拦的是 renderer 侧的 XHR / sendBeacon 通道。另有无出口机器上的另一半问题——hidden Electron renderer 会走主进程 electron.net.fetch 请求 ab.chatgpt.com/v1/initialize,polyfill 管不到那条通道,导致页面卡在启动 splash——由 #58 在同一控制面上补短路(两者互补、互不冲突)。#58 目前基于 #57official-runtime.cjs 的上下文依赖),#57 合并后可 rebase 到 main。

@RyensX

RyensX commented Sep 17, 2026

Copy link
Copy Markdown
Owner

相关修改,可以尽量使用虚拟骨架实现,而不是直接修改

新增 web.runtime.network.telemetry-guard 后,仓库里 6 个测试文件把修改点总数与 host/前缀分布硬编码为 103,需要同步为 104(browser 37→38、web.runtime. 37→38)。同时移除 zh-CN 语言包里多余的新增 key:该文件此前不承载任何 runtimeCompatibility.point.* 文案(中文以 catalog.ts 的描述为准),保留会破坏既有约定。
新增 web.runtime.network.telemetry-guard 落在 web-network 组,分组分布断言该组计数 3 -> 4。
compatibility-service 中"合并一个外部插件点后的快照长度"断言基数随之从 104 变为 105。
按骨架约定补齐四处接线与规范缺口:

1. check-modification-boundaries 仍把点数硬编码为 103。它是 build:gateway 的
   pretest 环节,新增点让 dist 变成 104 项后,全新构建会在编译阶段直接抛错,
   CI 与本地干净构建都会失败(实测 pnpm run build:gateway 退出码 1)。
2. 逐文件回退加载路径漏装该 Provider:官方 bundle 含 eager script 或存在外部插件时
   canBundleRuntimeBootstrap 为 false,Provider 根本不加载,修改点会在 locate
   阶段被判 unsupported。补进与 tooltip-dismiss 同样的 runtimeScript 序列。
3. Provider 在 installer 末尾无条件 emit,违反 docs/MODIFICATION_SKELETON.md 的
   "安装完成只代表 ready""不得在 installer 完成时上报 hit"。改为在 send/sendBeacon
   真正吞掉遥测时逐次上报,调试页由此反映真实流量;测试同步断言安装后 emits 为 0、
   透传流量不计数、每条被吞请求计一次。
4. 新测试断言 zh-CN 也必须给点描述,与仓库现状冲突:zh-CN 语言包不含任何
   runtimeCompatibility.point.* 键(中文由 catalog.ts 描述经 metadataText 回退)。
   改为断言该约定,并顺手把测试文件登记进 package.json 的 test 脚本,
   否则 pnpm test 永远不会执行它。
@yorkane
yorkane force-pushed the codex/statsig-telemetry branch from 809edf5 to f629b2f Compare September 17, 2026 04:37
@yorkane yorkane changed the title fix(polyfill): block Statsig telemetry over XHR and sendBeacon fix(polyfill): serve Statsig XHR and Beacon telemetry guard as a skeleton provider Sep 17, 2026
@yorkane

yorkane commented Sep 17, 2026

Copy link
Copy Markdown
Contributor Author

相关修改,可以尽量使用虚拟骨架实现,而不是直接修改

#56 已 force-push 换成骨架版

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.

2 participants