今天 Hacker News 上有一篇调查报告很有意思。作者原本只是在清理磁盘空间,发现 ~/.zcode 占了 700MB 以上,顺着目录往下查,挖出了一条几乎没人被告知的后台管道:只要客户端处于登录状态,它就会把整个工作区打包、加密、直传到云上对象存储。

一、证据链:从 700MB 到一个加密包

作者在检查点目录里发现一个 313MB 的加密文件和一个状态元数据文件,前者对应的是一次 345MB 的工作区快照,附带的上传失败计数已经累计到 564 次——也就是说,上传一直在重试,只是没成功。反编译客户端后,流程就很清楚:客户端先向服务端申请上传凭证,服务端返回对象存储的表单签名、大小上限和一枚 RSA 公钥;客户端本地用 AES‑256‑CTR 加密,再用这枚公钥包裹对称密钥,最后把加密包直接投递到云对象存储,由存储回调服务端登记快照。

二、最刺眼的一点:解密钥匙不在你手里

加密本身没有问题,问题在于那把 RSA 公钥是服务端在握手时临时下发的,对应私钥从不下发到本地。作者把本机所有私钥都试了一遍,解不开那 313MB 密文,客户端自己也解不开。如果这个功能真的是为了给用户做回滚或跨设备同步,钥匙理应在用户手里;只有服务端能解,说明这个密文的设计目标就是 "服务端随时能读"。

挂在金属柱上的旧挂锁

三、被上传的远比"当前代码"多

快照清单显示,四万两千多个文件里,.git 目录占了约 86.6%:LFS 缓存约 56.8%、对象库约 29.6%、reflog 约 0.2%。这意味着云端拿到的不只是当前工作区,而是仓库从第一天起的完整沿革——包括后来被删掉的历史密钥、还没推送的本地分支名(往往提前暴露未发布的功能计划),以及 .git/config 里的内部代码托管主机名与路径。

四、界面上那两个开关关不掉它

作者逐一核对了设置项:"优化体验" 只管是否允许把数据用于模型训练,"仓库快照索引" 只管服务端要不要对已上传快照建索引,两者都不控制本地打包与上传。采集与上传的旁路组件在启动时无条件实例化,唯一前置条件就是登录令牌有效。作者实测:手动删掉待上传的包,半小时内就会重新打包,失败计数继续往上加。

五、可以怎么防,以及这件事真正的启示

作者给的方案很实在:删文件是打地鼠,最有效的做法是在文件系统层面把这个目录设为不可写——macOS 用 chflags uchg,Linux 用 chattr +i。代价只是 "检查点回滚" 这类界面功能不可用,日常对话与代码补全不受影响;要恢复也只是取消这个标记。

对做项目交付的团队来说,这件事的启示不在于 "某个工具不能用",而在于必须把 AI 编码工具的数据流向纳入供应商审查。推理需要上下文是行业惯例,但整仓快照是另一回事:客户代码未经授权流出,在保密条款上就是实打实的风险。敏感项目用干净的机器、独立的账号,或者干脆把它关进容器里跑,都比事后追责便宜得多。