原博客: https://blog.ferstar.org/posts/zcode-silent-workspace-snapshot-upload/
在 zcode 里面让 ai 自己看了一下,结论是全部属实,下面是 ai 的结论:
我先读一下这篇博客说了什么,再在本机核实它的说法。
博客的核心指控是:ZCode 会在登录状态下把整个工作区(含完整 `.git` 历史)打包加密后直传阿里云 OSS,且解密私钥只在服务端。我现在直接在本机(你正在运行 ZCode 的这台 Windows)核对它列出的每类证据。
`v2/checkpoints` 目录存在,结构和博客描述完全一致(`pending/*.tar.gz.enc` 258MB 、`envelope.json`、`manifests/`、`extra-manifests/`、`state.json`)。继续读这些文件核对具体字段。
`state.json` 和 `envelope.json` 与博客描述的字段一字不差(AES-256-CTR + RSA-OAEP-SHA256 包裹密钥、`kind: baseline`、`failureCount`、`uploadCredentialHandle`)。这台机器上确实有一个针对 `Desktop\motionanalysis` 工作区的 258MB 加密包在上传队列里。接下来看清单文件里装了什么、以及上传去向的证据。
Manifest 确认包含 `.git/` 内容和工作区数据文件; extra-manifest 确认把全局配置(`settings.behavior.json`、`skills.json`)也一并打包 —— 与博客说法一致。现在查上传日志和设置开关。
关键实锤:清单里 `.git/objects/pack/pack-*.pack` 一项就是 **257MB 的完整 git 历史包** —— 这正是那个 258MB 加密文件的主体。继续查日志里的上传记录和设置开关。
桌面端程序在 `AppData\Local\Programs\ZCode`。现在验证博客里最关键的指控:代码里是否存在 `upload-credential` 上传链路,以及设置开关的实际作用。
Node 可用。写个脚本在 `app.asar`(307MB)里搜博客提到的关键字符串。
小 bug(初始 tail 用了字符串),修正后重跑。
代码层面的关键字符串全部命中。再深挖两点:①上传是否直传 OSS(找 `x-oss` 表单字段);②抓取/上传有没有任何开关能关掉。同时查 9/9 那次上传失败的实际日志。
代码里找到了 OSS 直传表单的完整构造(`policy`/`x-oss-signature`/`x-oss-security-token`/`callback`),与博客描述一致。再确认:①快照 sidecar 的创建是否有条件(能否关掉);②有没有环境变量开关。
没有发现任何能关闭抓取/上传的环境变量或设置键。最后核对两点:①其他工作区的 state.json 是否显示“上传成功后清理”(比失败更有力);②快照恢复走什么接口(验证解密是否只能在服务端)。
证据链已经闭合。最后取一下应用版本号,然后汇总。
# 结论:博客说的机制在这台机器上全部属实
我在你正在运行 ZCode 的这台 Windows 本机上逐条核对了博客的证据链,每一条可检验的技术指控都得到了印证。本机安装的是 ZCode 桌面端 3.12.3.7463 。
## 本机磁盘上的实物证据
`C:\Users\xxx\.zcode\v2\checkpoints\` 存在,结构与博客描述完全一致:
- **`pending\...tar.gz.enc`(258MB)**——针对 `Desktop\motionanalysis` 工作区的加密快照,2026-09-09 生成,`state.json` 显示 `attemptCount: 1, failureCount: 1`,即已尝试上传一次失败,正在队列里等重试。
- **`envelope.json`** 字段与博客一字不差:`contentAlgorithm: "aes-256-ctr"`、`keyWrapAlgorithm: "rsa-oaep-sha256"`、`encryptedDataKey`(被 RSA 包裹的 AES 密钥)。代码确认这个 RSA 公钥来自服务端 `upload-credential` 响应的 `encryption.public_key` 字段——**解密私钥只在服务端,本地无法解开这个文件**。
- **明文 manifest** 证明打了什么:151 个文件里包含 `.git/objects/pack/pack-*.pack` 一个 **257,535,221 字节(约 246MB)的完整 git 历史包**——占整个加密体的 99.5%。也就是说这个快照的主体就是完整 Git 历史,不是“任务上下文”。
- **`extra-manifests\`(schema `repo_snapshot_extra_manifest/v1`)确实把全局配置也打包了**:`settings.behavior.json` 和 `skills.json`,source 标注 `app-memory:global-settings`,跨工作区共享。
## app.asar(307MB)里的代码证据
对桌面端主程序做了二进制字符串检索,全部命中:
| 博客指控 | 代码实证 |
|---|---|
| 上传凭证接口 | `Wn(process.env, "/api/v1/snapshot/upload-credential")`,3 处;`VITE_ZCODE_ENDPOINT_ORIGIN: "https://zcode.z.ai"` |
| 直传阿里 OSS | `buildOss...` 函数构造 multipart 表单:`key/policy/x-oss-signature/x-oss-signature-version/x-oss-credential/x-oss-security-token/x-oss-date/callback/success_action_status:200` |
| 每次提问前抓取 | `captureBeforePrompt(...)` 在发送 prompt 前调用,无任何设置检查,只判断 sidecar 是否存在 |
| 任务结束时抓取 | `captureStage: "terminal", content: "repo-wiki-update"` |
| 无法关闭 | 检索不到 `snapshotUploadDisabled`/`disableRepoSnapshot`/`REPO_SNAPSHOT` 环境变量或任何抓取开关;`repoSnapshotIndexingEnabled`(默认 false)只控制服务端索引,`optimizeAgentExperienceEnabled`(默认 false)只控制训练相关,均不影响抓取上传 |
另外代码里还有硬编码的阿里云 ARMS 遥测端点(`proj-xtrace-*.cn-beijing.log.aliyuncs.com` 的 RUM 和 OpenTelemetry 上报),这与作者抓包只看到 zcode.z.ai + 阿里节点的观察吻合。
## 最有力的一条:这台机器真的传上去过
`checkpoints\1bc9bcfc9136\state.json`(工作区 `Desktop\Mano_hand`,2026-09-15)记录了 `lastAcceptedManifestHash` / `lastAcceptedManifestPath`——**服务端已接受该快照**,本地的 `.enc` 已被清理。这是一个 2.36MB 的成功上传。而客户端代码里只有 `upload-credential` 一个快照接口,**没有任何 restore/download 接口**——数据是单向出去的,这也印证了作者“排除备份/同步用途”的推理。
## 我没能独立验证的部分
- 我没有自己做抓包,OSS 目标 bucket 是运行时由服务端下发的(代码结构与作者描述一致,但没有硬编码 bucket 地址)。
- 隐私政策文本是否披露此事,属于作者的解读,我没有逐字核对。
- “564 次失败重试”是作者机器上的情况,你这里是 1 次。
## 如果你想止血(Windows 版做法)
博客的 `chflags`/`chattr` 是 macOS/Linux 的,Windows 等价方案是:清空并删除 `~\.zcode\v2\checkpoints` 目录,然后在原位置创建一个**同名只读文件**(让 `mkdir` 永远失败),或用 NTFS ACL 对该目录拒绝写入。按作者经验,代价是失去检查点/时间线回滚功能,编码和对话不受影响。另外那个 258MB 的 pending 文件删掉后只要目录可写就会被重新打包重传,所以要么锁目录、要么退出登录。需要我帮你把防护做上的话说一声。

