AI Craft(九):测试全绿之后,我继续验证 Review Craft

3975 字
20 分钟
AI Craft(九):测试全绿之后,我继续验证 Review Craft

AI Craft 工程实践 · 第九篇,Review Craft 案例补篇。 本文记录真实产品源码上的缺陷研究与本地修复。实验使用隔离测试仓库,不涉及客户代码或生产事故。本文中的 Review Craft 修复候选通过本地验证,尚未提交、发布或更新全局安装;文章发布不代表这些修复已上线。

为 Review Craft 写技术报告时,我一直绕不开一个问题:一个要求别人提供证据的审查工具,怎样证明自己的验证机制值得信任?

第二篇介绍了它如何组织源码锚点、覆盖范围、候选判断和交付证据。继续做下去,我开始用它自己的历史代码检验这些主张,再把发现的问题带回当前实现。

这次经历中,最值得记录的一个时刻是:源码身份修复的首轮 217 项测试全部通过,安装包检查也通过,但独立复核仍发现了两个会错误接受旧验证的漏洞,以及一个范围隔离问题。

我为这三个问题补了修复与回归,最终 220 项测试通过。增加了三项测试,并不能直接说明系统提高了多少;它们有价值,是因为确实阻止了之前能够发生的错误。

从一个已经修过的真实缺陷开始#

最初选择的案例来自 Review Craft 的历史实现:读取 Git 状态时没有检查命令退出码。

正常情况下,干净仓库的 git status --porcelain 可以没有输出。但当 Git 因配置错误而执行失败时,也可能没有标准输出。如果只看输出是否为空,就可能把“状态读取失败”解释成“工作区干净”。这两个状态会把后续验证带向完全不同的结论。

我先固定修复前后的源码,用独立夹具确认历史问题与原修复,再开展一组有工具的审查对照。两组使用同一份冻结代码和隔离工具环境,主要差别是是否内联固定版本的 Skill 正文。

结果是,两组都发现并运行复现了这个已知缺陷。它们还提出了隐藏未跟踪文件、子模块身份和快速预检计数等额外问题。

这里的“原生对照”仍运行在同一宿主环境里,有共同指令与工具;Craft 组也只是固定正文条件,并不是完整安装、路由和所有参考文档的综合对比。每组只有一次有效运行。因此,这个结果只能说明两组在本例上的表现,不能证明 Craft 相比原生审查有稳定优势。

一次失败,不一定证明了模型声称的原因#

额外问题中,有一项与可执行权限有关:同样的脚本字节,从 0755 改成 0644 后,源码指纹没有变化,旧验证仍被接受。

原生组报告了这项问题,并把脚本无法执行作为影响证据。Craft 组也尝试验证,但先运行正常 0755 脚本时,就得到了 PermissionError;该项没有进入它的最终发现。

我随后检查同一实验环境,发现工作目录挂载为 noexec。在这个环境里,两种权限下都不能直接执行脚本;通过 /bin/sh script 解释执行则都能成功。

于是,这项发现必须拆成两个判断:

  • 指纹缺口成立。 权限变化前后的指纹相同,可执行位没有参与身份判断。
  • 执行失败的归因尚未成立。 正常权限的前置对照也不能执行,因此当时不能证明失败由权限变化引起。

后来,我换到能够执行脚本的本机临时目录,补上了完整对照:先成功执行 0755 脚本,再保持字节相同、改成 0644,随后直接执行得到 PermissionError。这才补齐了新的因果证据。

后补的证据可以确认问题,却不能倒过来改写模型当时的成绩。 同样,Craft 最终少报了一项,也不能直接被解释成误报更少。这次实验让我更明确地要求:在把失败归因于某个变更之前,先证明正向对照在当前环境中确实成立。

把额外发现带回当前版本#

历史代码中的问题不一定仍存在。我以当前本地基线 76b44945ba2d2efa4665f6ad10842c860179bb1b 重新构造案例,确认原 Git 退出码修复仍有效,并复现了四项额外缺陷。

  1. 隐藏未跟踪文件。 配置隐藏显示后,未提交源码可能被当成干净状态。修复需要明确指定未跟踪文件检查语义。
  2. fast 文件预算。 1 个源码加 201 个应排除文件,被按 202 个有效文件拒绝。修复需要复用正式覆盖分类的计数逻辑。
  3. 子模块身份。 子模块代码与 gitlink 都变化后,旧源码指纹仍被接受。修复需要绑定 gitlink 与实际 checkout。
  4. 可执行位身份。 文件字节相同,执行属性变化后仍复用旧验证。修复需要将执行属性纳入身份与变更判断。

前两项先做有界修复。快速预检没有放宽原来普通源码 200 个文件的上限,而是让生成、第三方和二进制文件回到正确的分类。隐藏文件检查则保留 Git 的忽略规则,不修改用户配置。Git 状态选项

后两项需要一起考虑源码身份及历史证据的兼容性。单独改一个最终状态标签,不能解决错误验证为什么还能被复用的问题。

深入一个修复:源码相同究竟意味着什么#

原来的普通文件指纹主要依赖路径、类型、内容摘要和分类;子模块目录被记录为普通的特殊条目,摘要没有绑定依赖提交。

这套信息能够发现很多文本变化,却不能表达两类执行差异:文件变得不能直接执行,或者依赖换成了另一份代码。

我把内容摘要与源码身份分开保留。sha256 继续表达普通文件字节;新增的 sourceIdentity 记录执行属性或子模块的 Git 身份。这样,报告仍能解释“内容没变,但身份变了”,不必把两件事混成一个不可解释的状态。

下面是新字段的简化表示;A、B 是提交标识的示意占位,不是实际回执:

普通文件:
内容摘要保持不变
executable: true → false
结果:源码指纹改变,旧验证失效
子模块:
index gitlink: A
实际 checkout: A → B
结果:即使父仓库尚未暂存新 gitlink,身份也已改变

两份提交信息各有作用:gitlink 表示父仓库记录的依赖版本,checkout 表示眼前实际检出的版本。只绑定其中一份,仍可能遗漏另一侧的变化。

子模块未初始化时,checkout 显式记录为 null,目录缺失也不会抹掉 index 中的 gitlink。嵌套子模块身份汇总进顶层条目。这个条目仍是原子身份记录,没有把内部源码计入“已经审查”的覆盖范围。

新信息还必须贯穿后续链路。我把它保留到 fix 的 baseline/current、attempt evidence 和指纹计算中,让纯身份变化进入 MODIFIED 台账。两个交付协议都构造了完整测试:先形成有效修复验证,再改变执行位或子模块提交,确认交付拒绝旧验证,并检查失败回执本身符合格式与内容合同。

测试全绿之后,独立复核改变了实现#

做到这里,首轮 217 项测试和临时安装 E2E 都通过了。我仍把这次涉及证据完整性的改动交给一个独立上下文的 AI Reviewer 做有界只读复核。

它没有只重复既有测试,而是另外构造了三个 Git 场景。

元数据正确,也可能根本没有选中那个文件#

当 core.filemode=false 时,diff 路径选择仍可能忽略纯执行位变化。文件没有进入 inventory,后面再完整的身份字段也无从比较。原夹具让共享交付收集器返回了 VERIFIED / clean=true。

修正后,POSIX 下的工作区状态检查与 diff 选择都明确检测执行位。再次重放,旧验证被拒绝,工作区也不再被错误标为干净。

子模块的“空状态”仍有前提#

子模块文件设置 assume-unchanged 或 skip-worktree 后,内部修改可能不再出现在通常的状态检查里。这些 index 标记本来就会影响 Git 如何处理工作区文件,不能无条件把它们存在时的空状态当作本工具的完整证据。Git index 标记说明

当前修复选择明确拒绝这些隐藏状态,检查包含已初始化的嵌套子模块。它没有宣称能够自动审查任意脏子模块,也没有假装已经建立了恶意文件系统下的原子快照保证。

范围过滤也必须发生在正确的位置#

原来的 inventory 在应用排除规则之前,就读取全仓 Git 状态。一个已排除但 .git 损坏的子模块,仍能让 inventory 提前失败。

我将仓库探测与完整状态查询分开,让 inventory 先筛选范围,再检查入选子模块。同时保留另一个明确要求:preflight 和交付仍要检查全仓状态,无法完成这个检查时可以拒绝。范围内的源码身份,与整个工作区是否可验证,是两个不同承诺。

三项修正完成后,同一位 Reviewer 重新检查了最终源码,独立执行 10 项专项测试,并逐项确认原发现关闭。这是 AI 辅助的独立代码复核,不是独立人类审查,也没有被包装成一次 canonical assured 审查。

最终结果能证明什么#

我保留了首轮候选与失败发现,并重新冻结最终候选。最终结果如下;这些数字来自各阶段实际回执,本篇写作没有重复运行产品测试。

  • 最终全量测试: 220 项通过,测试阶段 237.734 秒;源码、Schema、Lint 和复杂度门禁全部通过。
  • 精确临时安装 E2E: 86 个文件的候选包通过安装及相应流程检查。
  • 独立代码复查: 10 项专项测试通过,三个发现关闭。
  • 原五个独立回归案例: 全部通过,包含历史退出码护栏与四项额外缺陷。
  • Windows 真机、远端 CI、正式发布: 本轮未验证或未执行。

这几行不能相加成为“发现了多少真实问题”或“审查准确率”。220 项是工程回归,不是 220 次真实模型审查;安装 E2E 证明候选包能完成指定流程,不证明用户的全局安装已经更新。

本轮的修复由我确定范围、验收与取舍,结合 Agent 完成实现和测试,再用独立 Reviewer 补充反例。我希望沉淀下来的能力,是把一个疑点转成可检验的问题,并让修复后的行为有机会再次被推翻。

仍然存在的限制#

身份字段变强也有兼容成本。没有新字段的旧记录仍按原算法计算历史哈希,不能被自动补写成“拥有新保证”的记录。当前实时采集使用新身份后,旧 run/fix 即使没有文本变化,也可能需要重新 preflight 和验证。

执行属性目前覆盖 POSIX owner-executable 位;Windows 分支绑定 Git index 中的执行标志,未做真机验收。其他权限位、ACL、挂载选项和解释器是否可用,都不属于这个字段的承诺。前面的 noexec 经历已经说明,源码身份正确也不等于执行环境一定正确。

子模块检查仍依赖 Git 对普通脏状态的判断,并拒绝本次已证实会隐藏变化的 index 标记。它不是任意缓存、并发修改或恶意文件系统条件下的完整防护。大规模嵌套子模块的耗时、跨平台身份迁移成本,也还需要单独验证。

最后,这批案例由维护者选择,其中的缺陷已经进入开发历史。它们能作为回归资产,却不能再被当作未知任务上的泛化证明。

RSI 的下一步,需要增加什么证据#

这轮形成了“发现失败—修复—回归—独立复核”的工程反馈过程,但尚未证明递归自我改进。当前没有一个经过验证的新版本,持续改进自己的下一轮诊断或候选生成能力,并在独立任务上获得可复现的净收益。

接下来的实验,我会沿用第二篇的研究设计,把这批已见问题留在开发侧,并在运行前固定三件事:

  1. 候选可以改什么。 先限定一段审查指导或参考组织,固定程序校验、评测标准与发布控制。若要研究工具代码修改,另设批次,避免无法解释收益来自哪里。
  2. 怎样决定采用。 固定版本与候选版本使用相同模型、工具和任务预算,按任务配对检查有效发现、已知缺陷遗漏、合理代码上的误报和执行失败。采用阈值与停止规则必须先于结果。
  3. 怎样检验下一轮。 候选只接触开发材料;未见任务按相关缺陷组隔离。候选生成、运行、失败尝试和人工裁定的成本都计入。结果一旦被用于下一轮修改,就不能继续冒充未见验收集。

即使第一轮候选变好,也只是一次受控改进的证据。要讨论递归性,还需要观察它是否改善后续改进过程,而不是不断对同一批题目加规则。

对我来说,这次最明确的进展是:Review Craft 开始有了一批能够质疑自身的案例。它们既能支持技术报告,也能在下一次修改时提醒我,哪些“看上去已经验证”的结论,其实还缺了一个前提。

版本与证据说明#

  • 记录日期:2026 年 9 月 13 日;最终本地环境为 macOS ARM64、Python 3.14.7、Node.js v24.18.0。
  • 公开基线源码:本文修复基于该 commit 加本地候选修改;此链接不包含本文的新修复。
  • 最终候选源码归档 SHA-256:a3b9c9db1df138fff15cba51a0c723bcc9218fbb383760c962c568c264b4eb89。
  • 最终候选安装包 SHA-256:10a4fcd940cfbe30c534b32600719bbae38d4d40e4dc83721c0f596428c82960。
  • 候选与完整回执目前在本地研究档案中,尚未随本文公开。以上哈希用于明确本文绑定对象,不等同于读者已能下载并独立复现。后续公开时应补对应源码与脱敏回执入口。
  • 本轮修复没有新增模型对照实验;独立代码 Reviewer 的两阶段复核单独记录。历史有工具对照、后续作者复现与产品修复是不同阶段,不能合并成模型的一次成绩。

系列阅读:总览 · Review Craft 机制与研究计划 · 上一篇:Reverse Craft

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!

打赏
AI Craft(九):测试全绿之后,我继续验证 Review Craft
https://whois67.52671314.xyz/posts/ai-craft-09-review-craft-source-identity-case/
作者
whois67
发布于
2026-09-13
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
whois67
Hello, I'm 67@sixseven……
公告
欢迎来到 whois67 的博客,站点还在逐步完善中。
分类
标签
最新动态
站点统计
文章
12
分类
6
标签
32
总字数
51,404
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
Cloudflare Pages
博客版本
Firefly v6.15.4
文章许可
CC BY-NC-SA 4.0