某AI编程工具的reviewChanges功能默认关闭,导致AI直接写入文件跳过审核,揭示了AI编程安全边界的关键工程问题。
96% 的开发者并不完全信任 AI 生成的代码。其中只有 48% 在代码发布前对其进行了验证(Sonar, 2026)。
这道鸿沟就是我们产品存在的原因:每一个 AI 变更都会以 diff 形式呈现在你面前审查通过后,代码才会进入你的项目。
上周我发现我们的审查门禁默认是关闭的。
功能是正常的。只是没人触发过它。
问题从来不在机制层面。Agent 在工具边界处被拦截,任何内容在触及磁盘之前就已停止。你会得到一个真正的 unified diff,然后运行过程会等待。这里没有超时机制,因为用户走开了就意味着没有批准任何内容。
同时还特意留了一个"Approve the rest"按钮。冷启动构建会写入几十个文件,反复询问几十次只会导致机械式审批——而这完全背离了门禁本身的意义。
所有这些都发布并正常运作了。然而 reviewChanges 默认为 false。
所以新用户得到的,是和我们所描述的痛点一模一样的"不问就写"行为。我们悄无声息地成为了那 52% 不做验证的人。
我发现这类 bug 只有一种方式能发现:跑一个真实的构建,然后观察 agent 在工作区里创建一个文件,全程没有问我任何问题。
有两件事更糟糕
你批准的 diff 不一定是实际写入的 diff
门禁运行在原始工具参数上。而预写钩子——可以重写文件内容——在用户确认之后才执行。
所以如果钩子重写了内容,你批准的是一个变更,实际到达磁盘的是另一个。在一个审查功能上,这不叫 bug,这叫欺骗。
现在的顺序是:安全钩子 → 钩子修改 → 用户审查最终参数 → 写入。
一次重试终结了整个运行
当用户拒绝一个变更时,模型有时会重新提案。我们对此做了上限:
const MAX_REPEATS = 2; // repeats allowed before the turn is ended outright
检查逻辑是 seen + 1 >= MAX_REPEATS,而 seen 已经是之前拒绝的次数。所以第一次重复就触发了条件,协调器直接中止了整个运行。
一次无辜的重试杀死了用户正在做的一切。
现有测试断言第三个请求会停止运行。它从未断言第二个请求不会停止运行。
一个默认为 off 的特性标志和一个从未构建过的特性无法区分。无论哪种情况你的测试都会通过。无论哪种情况你的 changelog 都会说你已经发布了它。你的 CI/CD 管道里没有任何东西能区分"已构建"和"可达"。
61% 的开发者说 AI 生成的代码看起来正确但实际并非如此——无声的失败。一个悄无声息地默认为关闭的审查门禁,正是那种失败模式,只是发生在你自己的产品上。
修复只是一个布尔值。但发现它需要像用户一样运行这个东西,然后观察它实际做了什么。
Originally published at nocoder.codes.