oh-my-openagent 重命名变更集代码质量审查实录:agent-command-string 审计闸门为何在 1190 个测试中唯一飘红
2026/9/19 4:02:59 网站建设 项目流程

oh-my-openagent 重命名变更集代码质量审查实录:agent-command-string 审计闸门为何在 1190 个测试中唯一飘红

【免费下载链接】oh-my-openagentOmO: Just type "mass ulw" keyword with your prompt. Now you are the master of graph engineering.项目地址: https://gitcode.com/gh_mirrors/oh/oh-my-openagent

导读

本文以 oh-my-openagent(OmO)仓库内 .omo/evidence/20260809-omo-agent-toolkit-rename/F2.md 这份代码质量审查(Code-Quality Review)报告为主线,完整还原一次omoomo-agent-toolkit重命名变更集从 typecheck、全量测试、仓库法则对照到违规项判定的全过程。你将看到:一个"上线即永久变红"的审计闸门(audit gate)如何因自我匹配(self-scan)而失效,一行代码的修复为何足以让 1190 个测试从 1 红恢复全绿,以及#given/#when/#then测试法则、无行号指纹、allowlist 分类等工程约束在 script/agent-command-string-scan.ts 等源码中的真实落地形态。


1. 审查背景:一次跨 142 个文件的重命名重构

本次审查针对的是omo-agent-toolkit重命名变更集,其元数据如下:

  • Worktree.local-ignore/worktrees/omo-agent-toolkit-rename(分支feat/omo-agent-toolkit-rename,基于origin/dev的 7 个提交)
  • 审查 Diffgit diff origin/dev...HEAD,共 142 个文件;排除.omo证据产物后,可审查源码 diff 为 3,323 行
  • 审查者:senpi-task 子任务st_019fe5d1,只读分析,所有结论均通过实际执行命令验证

审查遵循三条主线:真实命令结果(typecheck、scoped tests)、仓库法则对照(AGENTS.md 的硬性约定)、测试质量评估(AI-slop 注释与同义反复检查)。所有结果都标注为 "REAL RESULT",强调不是推理而是运行产物。

重命名的最终形态可以从当前 package.json 的bin映射看到——omo条目已被移除,omo-agent-toolkit与四个保留别名(oh-my-opencodeoh-my-openagentlazycodexlazycodex-ai)共同指向共享入口bin/oh-my-opencode.js

"bin": { "oh-my-opencode": "bin/oh-my-opencode.js", "oh-my-openagent": "bin/oh-my-opencode.js", "omo-agent-toolkit": "bin/oh-my-opencode.js", "lazycodex": "bin/oh-my-opencode.js", "lazycodex-ai": "bin/oh-my-opencode.js" }

2. 第一道关卡:全仓 typecheck 零诊断

审查命令bun run typecheck(tsgo 根项目 +typecheck:script+typecheck:packages,覆盖 29 个 package 项目)

真实结果

TYPECHECK_EXIT=0

PASS。根目录、script/以及全部 package tsconfig 均零诊断通过。对一次横跨 142 个文件、涉及 bin 映射、CLI 安装参数解析、postinstall 脚本的重命名来说,类型层面的完整性是第一道必须迈过的门槛——这一关干净通过,说明重命名没有破坏任何导出签名与调用关系。

3. 第二道关卡:scoped 测试 1,190 例 1 红

审查命令

bun test bin script packages/omo-opencode/src/cli packages/omo-senpi/src/components/ulw-loop

真实结果

TEST_EXIT=1 1189 pass 1 fail 2929 expect() calls Ran 1190 tests across 186 files. [11.83s] (fail) agent command string audit > #given tracked source files #when legacy agent and human commands are scanned #then every hit is categorized

FAIL — 唯一一条红测试,且已用bun test script/agent-command-string-audit.test.ts单独复现(0 pass / 1 fail),排除排序或偶发(flake)因素。失败 diff 如下:

@@ collectHits() vs allowlist @@ + "script/agent-command-string-audit.allowlist.json:5: omo ulw-loop", + ... (33 hits total, ALL inside script/agent-command-string-audit.allowlist.json itself) - Expected - 0 + Received + 33 at script/agent-command-string-audit.test.ts:57:27

3.1 根因:审计闸门自我匹配,永远无法通过

这条红测试不是代码回归,而是审计机制自身的逻辑缺陷。审计闸门会扫描每一个git ls-files追踪的文件,用正则\bomo (ulw-loop|boulder|install|...)\b等模式查找遗留命令字符串;但isExcluded()(审查时位于 script/agent-command-string-audit.test.ts 第 16-22 行)没有排除 allowlist 文件自身

问题因此成立:allowlist 的每条目本身就是一个遗留命令字符串(例如script/agent-command-string-audit.allowlist.json:5: omo ulw-loop),于是闸门对自己扫描出了 33 次未分类命中。变更集的最后一个提交("migrate remaining agent commands … with an audit gate")因此落地了一个永久变红的闸门——这恰恰是审计闸门要防止的事情。

3.2 修复方案:一行排除

审查给出的修复只有一行,把 allowlist 加入isExcluded()排除列表:

|| filePath === "script/agent-command-string-audit.allowlist.json"

(备选方案是在collectHits()中跳过ALLOWLIST_PATH;但放进isExcluded更简单,且与既有 CHANGELOG /.omo的排除模式一致。)

这一修复在当前仓库源码中已经落地:查看 script/agent-command-string-scan.ts 的isExcluded(),可以看到排除列表已包含ALLOWLIST_RELATIVE_PATH(即 allowlist 自身),与审查建议完全一致:

export function isExcluded(filePath: string): boolean { return filePath === ALLOWLIST_RELATIVE_PATH || filePath === AUDIT_TEST_RELATIVE_PATH || filePath === SCAN_MODULE_RELATIVE_PATH || filePath === SCAN_TEST_RELATIVE_PATH || filePath === "CHANGELOG.md" || filePath.endsWith("/CHANGELOG.md") || filePath === ".omo" || filePath.startsWith(".omo/") || filePath.split("/").some((part) => part === "node_modules" || part === "install-dist" || part === "dist") }

3.3 审计闸门的机制设计:无行号指纹

为什么审计闸门要用"指纹"而不是直接比对行号?script/agent-command-string-scan.ts 中fingerprintSource()的注释给出了明确的安全理由:

Deliberately line-number-free: a release version stamp or a doc edit shifts every line below it, and a line-pinned fingerprint turns that shift into a red release gate. The count keeps the audit sensitive to a NEW legacy command occurrence inside an already-allowlisted file.

即:指纹刻意不携带行号——一次版本戳更新或文档编辑会把其下所有行号整体下移,行号固定的指纹会把这种行移变成一次虚假的发布闸门变红;而保留出现次数则让闸门对"已放行文件内新增一条遗留命令"仍然敏感。fingerprintSource()的实现要点:

  • 三个扫描模式(script/agent-command-string-scan.ts):AGENT_COMMAND_RE\bomo (ulw-loop|boulder)\b)、HUMAN_COMMAND_RE\bomo (install|uninstall|cleanup|doctor|run|get-local-version|version|mcp)\b)、BARE_BIN_REcommand -v omo/bin/omo=omo$(which omo)等裸二进制引用);
  • 指纹键为${filePath}: ${match[0]},出现次数大于 1 时以xN后缀标注;
  • 仅扫描git ls-files追踪文件(script/agent-command-string-scan.ts),并过滤排除列表、node_modulesinstall-distdist等目录。

配套的 script/agent-command-string-scan.test.ts 用三个场景验证了这个设计契约:行移位后指纹不变、已放行文件新增一条命令后指纹变化、全新文件中的遗留命令按路径上报。

3.4 闸门的断言结构

script/agent-command-string-audit.test.ts 包含两道断言:

  1. 分类闸门collectHits(WORKSPACE_ROOT)必须恰好等于 allowlist 中四个分类(emit-migratetest-expectationinput-compat-preservedocs)条目的并集;其中emit-migratetest-expectation必须保持为空数组(有意设计的"债务闸门"——任何人往这两个分类写入新条目都会触发失败)。
  2. 无行号 pin 约束:allowlist 条目不得携带路径:行号:前缀,防止文档与发布戳的行位移破坏发布闸门。

当前 script/agent-command-string-audit.allowlist.json 的input-compat-preservedocs分类展示了放行条目的形态,例如"packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts: omo ulw-loop""packages/omo-native/bin/lib/launcher.js: omo ulw-loop""AGENTS.md: omo doctor"等——每条都是"为兼容旧输入而有意保留"的遗留命令位置。

4. 第三道关卡:对照 AGENTS.md 仓库法则

审查将 diff 逐条对照 AGENTS.md 的工程法则,结果如下表(原文完整继承):

法则结果
禁止as anyCLEAN — 零新增(一处 grep 误报:文档行中的 "alias anywhere" 散文)
禁止@ts-ignore/@ts-expect-errorCLEAN — 零新增
禁止压制 lintCLEAN — 零新增eslint-disable或等价物
代码中禁止 emojiCLEAN — 无新增。packages/omo-senpi/plugin/extensions/omo.js中的⚡ ultraworking是已检入压缩构建产物中的既有内容,diff 仅重盖了 bundle 哈希并重命名了字符串
kebab-case 文件命名CLEAN — 新文件全部为 kebab-case(bin-map.test.tsagent-command-string-audit.test.tsagent-command-string-audit.allowlist.jsonpostinstall.test.ts
createXXX工厂模式N/A — 无新增组件/工厂;resolveOmoBin/toSpawnTarget是既有导出、原地修改
barrelindex.ts仅导出NOT INTRODUCED —packages/omo-senpi/src/components/ulw-loop/index.ts承载业务逻辑,但早于本 diff(hunk 仅替换omoomo-agent-toolkit字符串),属既有状况,不计入本次变更
~200 LOC 软性文件规模上限PRE-EXISTING OVERAGE WORSENED —packages/omo-codex/src/install/codex-cache-bins.ts由 229 行增至 255 行,本就超限,本次再增 26 行而未抽取。仅作观察(软性上限)
#given/#when/#then前缀测试、禁止 AAAONE VIOLATION — 见下方 V2,未出现 Arrange-Act-Assert
禁止空 catch 块CLEAN — 新增removeGeneratedRuntimeWrapper的 catch 对非 ENOENT 重新抛出;readActiveStatus为 log-and-return;压缩产物中的catch{}为既有输出
禁止万能 util/helper/service 文件CLEAN — 无新增

4.1 V1(BLOCKING):审计闸门测试在 HEAD 即为红

  • 位置:script/agent-command-string-audit.test.ts 分类闸门测试(审查时约第 57 行)
  • 问题:闸门未排除自身 allowlist,产生 33 次未分类自我命中,随包发布即永久失败
  • 违反理由:变更集不得携带一条红测试落地;一个永远无法通过的闸门比没有闸门更糟
  • 修复:在isExcluded()中排除script/agent-command-string-audit.allowlist.json,重跑套件至全绿

4.2 V2(minor):新测试缺少#given/#when/#then前缀

  • 位置:packages/omo-opencode/src/cli/install-platform-resolution.test.ts 第 170、180、190、200、208 行附近的五个OMO_EDITION install routing测试
  • 问题:使用纯英文描述名 + 裸// when/// then注释,全程无#given/#when/#then前缀,而仓库法则要求强制前缀。同一次 diff 中新增的doctor-target.test.ts测试带有前缀,说明 diff 内部风格不一致
  • 修复建议:改写为#given OMO_EDITION=codex #when resolving install args for a non-codex invocation #then the platform defaults to codex形式

从当前源码看,这五个测试仍然存在且描述名未变(如"OMO_EDITION=codex defaults a non-codex invocation name to the codex platform",第 170 行),说明该 minor 违规在审查后尚未完全清理——这是审查结论未被完全消费的可见证据。

4.3 V3(minor):bin-map 测试头部注释是 AI-slop

  • 位置:script/bin-map.test.ts 头部
  • 问题:第 1 行仅复述文件名(// script/bin-map.test.ts),第 2 行叙述变更事件("omo -> omo-agent-toolkit rename")而非陈述持久契约,均为噪音;describe字符串已经说明了被测内容
  • 修复:删除这两行

当前仓库的 script/bin-map.test.ts 已从 import 直接开始、头部注释被删除,V3 修复已经落地。

4.4 被检查且未标记的实质性 WHY 注释(应保留)

审查明确指出以下注释属于"解释非显然安全理由"的实质性注释,不得删除

  • ulw-loop 组件中 "Deliberately NO PATH lookup of the bare nameomo" 块与.jsspawn 说明(避免对裸名omo做 PATH 查找的刻意设计)
  • postinstall.mjs 中关于 npm ≥7 隐藏生命周期输出的说明(解释为何通知是 best-effort)
  • .github/workflows/publish.yml中升级模拟(upgrade-simulation)契约注释(记录"标记版 vs 用户自有遗留包装器"的安全不变量)
  • packages/omo-codex/plugin/components/bootstrap/src/setup.ts的降级路径注释(仅字符串更新)
  • .omo/evidence/20260809-omo-agent-toolkit-rename/ 下lead-codex-qa.shlead-npm-qa.sh的 ISOLATION CONTRACT 头部(隔离契约,属安全文档,经确认不予标记)

5. 第四道关卡:同义反复评估(每个新测试逐一过筛)

"同义反复"指那种无论如何都不可能失败的测试——它不检测任何真实行为。审查对本次新增的每个测试文件逐一评估:

5.1 script/bin-map.test.ts(3 个测试,均为真实变更探测器)

  1. …the omo bin entry is absent— 若omo被重新加回 bin map 即失败,真实有效
  2. …omo-agent-toolkit points at the shared entry— 若入口被移除或改指即失败,真实有效
  3. …the four surviving aliases keep the shared entry— 若四个别名任一漂移即失败,真实有效

5.2 script/agent-command-string-audit.test.ts(1 个测试)

  • …every hit is categorized非同义反复,是实时闸门(其当前恰好失败本身就是证明);但正如 V1 所示,随包发布状态下它无法通过,当前失败模式是自扫描而非真实回归。emit-migrate/test-expectationtoEqual([])断言是有意设计的债务闸门——任何人往这两个分类登记新条目都会失败,属于设计内行为

5.3 postinstall.test.ts(审查时为 3 个测试,均执行真实 postinstall.mjs 于隔离 fixture HOME)

  1. announces the omo-agent-toolkit rename exactly once— 通知被删除、改写或打印两次即失败,真实有效
  2. never fails the install regardless of platform binary resolution— postinstall 在 fixture 环境非零退出即失败。断言真实,但命名过度承诺:只覆盖一种环境形态,"regardless of platform binary resolution"并未做平台变化测试,属命名瑕疵而非同义反复
  3. stays idempotent across repeated runs命名不当:它断言两次运行各打印一次通知(运行间一致性);真正的幂等(第二次运行什么都不打印)反而会让该测试失败。建议改名为prints the notice exactly once on every run

审查结论:不存在无法失败的测试。每个新测试都命名了一个可被回归击穿的行为。

从当前 postinstall.test.ts 看,该文件已演进为 4 个测试并补齐了#given/#when/#then前缀:新增了finishes when the opencode version probe never returns(用挂起 opencode shim 验证 postinstall 在版本探测永不返回时仍能在超时前正常结束),且announces … exactly oncestays idempotent across repeated runs的断言逻辑保持与审查描述一致。

6. 审查裁决与修复闭环

6.1 最终 Verdict(原文)

One blocking defect (V1: the audit-gate test is red at HEAD by self-scan, confirmed by real test runs, full-suite and standalone) plus two minor violations (V2 missing#given/#when/#thenprefixes in the new install-platform-resolution tests, V3 slop header comments in bin-map.test.ts). Everything else — typecheck, remaining 1,189 tests, banned-pattern scan, naming, catches, comment quality, generated artifacts — is clean.

REJECT — fix V1 (excludescript/agent-command-string-audit.allowlist.jsoninisExcluded(), suite must go 1190/1190 green), V2, and V3, then re-submit.

即:拒绝合并(REJECT)。必须修复 V1(在isExcluded()中排除 allowlist 自身,套件须恢复 1190/1190 全绿)、V2、V3 后重新提交。

6.2 审查闭环的仓库现状印证

对比当前仓库 HEAD,可以观察到这次审查驱动的修复闭环:

  • V1 已修复:script/agent-command-string-scan.ts 的isExcluded()已将 allowlist 文件自身列入排除,正是审查建议的一行修复;
  • V3 已修复:script/bin-map.test.ts 头部两行噪音注释已删除;
  • V2 残留:packages/omo-opencode/src/cli/install-platform-resolution.test.ts 的五个OMO_EDITION路由测试仍使用裸// when/// then注释、无#given前缀,尚未按建议重命名;
  • postinstall 测试持续演进:由审查时的 3 个增至 4 个,并补齐前缀、新增挂起探测场景。

这正体现了 AGENTS.md 所强制的证据驱动工作流:.omo/evidence/20260809-omo-agent-toolkit-rename/目录下留存了 F1-F4 审查文档、lead-codex-qa.sh/lead-npm-qa.shQA 脚本与各任务日志,审查结论有据可查、修复进度可追溯。

7. 可复用的审查方法论要点

从这份 F2 报告可以提炼出一套可移植的变更集质量审查清单:

  1. 用真实命令结果说话:typecheck 与 scoped tests 必须实际执行并记录退出码与通过/失败计数,杜绝"应该能过"的推断;
  2. 红测试必须单独复现TEST_EXIT=1后先以单文件复跑(bun test script/agent-command-string-audit.test.ts),区分真实回归与排序/偶发;
  3. 闸门类工具要审查其自指性:审计/门禁工具若扫描仓库自身文件,必须确认排除列表覆盖自身输入(allowlist、测试、扫描模块、CHANGELOG、证据目录),否则会出现"闸门对自己 33 次命中"式的永久红;
  4. 法则对照要逐条留痕as any@ts-ignore、lint 压制、emoji、命名、空 catch、万能文件等每一条都给出 CLEAN / 违规 / N/A 的判定与证据;
  5. 区分实质性注释与 AI-slop:复述文件名、叙述变更事件的注释是噪音;解释非显然安全理由的 WHY 注释必须保留——并明确列出"不要删"清单;
  6. 测试逐条做同义反复检查:每个新测试都必须能指出"哪个行为回归会让它变红",命名不得过度承诺("regardless of platform" 却没有平台变化矩阵)。

【免费下载链接】oh-my-openagentOmO: Just type "mass ulw" keyword with your prompt. Now you are the master of graph engineering.项目地址: https://gitcode.com/gh_mirrors/oh/oh-my-openagent

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询