跳转至

验证

验证基准:main 分支 1629266e 上的 33b0643e(即该规则、knip 要求移除的别名,以及下文端到端运行所促成的固定长度子句)。在 macOS 上使用 Node v22.23.1 执行(仓库在 .nvmrc 中固定为 24.18.0,但该版本未安装)。

门禁

  • npm run build:cached、npm run check:fast(类型检查和 lint)、npm run format:check、npx knip、npm run scan:todos、npm run docs:check、npm run verify:test-discovery 和 npm run mcp-catalog:check:全部通过。
  • npm run jscpd:3561 个文件中有 3.49% 的重复行,共 3067 个克隆;main 分支为 3.49%、3068 个克隆,因为共享的 segment-limit 拆分减少了一个克隆。
  • oxlint 对变更文件未报告新的发现。清单累加器保留了 main 分支的三个警告(文件长度、其记录追加逻辑的复杂度和参数数量),仅多了一行。
  • npx vitest run --project domain --project services:7119 个通过,5 个原有跳过。
  • npm run test:prepare,随后 npm run test:focused -- 运行 analysis-view 的 MCP 与 CLI 边界、compact input schema 与 tool schema 有效性边界,以及环境 serve 与 export 边界:7 个文件,76 个通过。

environmentManifestView.test.ts 中的新测试覆盖:

  • 跨方法和深度共享的字面量,以及没有该规则时的同一捕获;
  • 拼写条件:相同类别和长度、大小写、缺少数字、冒号单词、版本;
  • 定长标识符族中没有数字的成员,与较短的单词、连字符值以及少于八个字符的族进行对比;
  • 保留工具自身规则的合并,包括在共享参数下使用 sibling-variance 参数;
  • 模板化配对的两半;
  • 格式规则位置和段限制。

展示捕获

50 个 showcase 捕获(45 个 HAR 检查和 5 个 capture_browser_scenario 捕获)分别使用 main 分支的构建和本分支的构建生成。

  • 在没有该规则的情况下,两种构建对每个捕获都给出相同结果:无规则的清单、带 after-uid-literal、opaque-token、sibling-variance 和 sibling-pair-variance 的清单,以及环境状态视图。150/150 个输出的哈希均相等。
  • 将 prefix-variance 添加到 after-uid-literal、opaque-token 和 sibling-variance 后,10 个捕获中的 69 个字面量工具被模板化,其中 25 个是写入工具:
  • Komga:collection 和 readlist 的 PATCH 与 DELETE,以及 book pages。
  • n8n:workflow 的 PATCH、DELETE 和 archive,以及 id 不含数字的 workflow 的读取。
  • Memos:memo 的 PATCH 和 DELETE、user settings 读取,以及两个 id 不含数字的 memo 的读取。
  • Navidrome:playlist 的 PUT 和 DELETE。
  • Mealie:recipe 的 PATCH 和 DELETE。
  • Grist:document 的 PATCH 和 DELETE,以及 table record 写入。
  • Redpanda Console:subject 和 topic 写入。
  • Sentry:release 的 PUT 和 DELETE。
  • Shlink:short URL 的 PATCH。
  • Mattermost:me 读取,sibling-variance 已将其并入 user 参数。

工具数量从 1591 降至 1578,因为 Redpanda Console 的按 subject 读取,以及按 memo、按 workflow 的读取被合并。

  • 该规则按预期放过的字面量包括 Espo CRM 的 layout、Federal Register 的 facets、Ghost 的 slug、Shlink 的 stats、Lychee 的 Metrics::photo 以及 Vault 的路径名。
  • 在启用该规则的情况下,环境状态视图在每个捕获上都成功。其类型移入模板化集合(字面量合并后从 531 变为 526);少一个条目的视图正是 Redpanda Console 的合并结果。

使用 #5600 的写入计划(其分支已在本地合并此提交与 main):

  • 获得服务的写入工具从 33 增至 39:Komga 的 collection create、update 和 delete;n8n 的 workflow delete;Sentry 的 release update 和 delete。
  • 没有状态目标的写入工具从 102 降至 87。
  • 新建模但仍未获得服务的工具受捕获内容所限:
  • 写入后没有读取:Komga readlists、Mealie、Navidrome、Redpanda Console;
  • n8n 的 item 读取显示了一个展开的 shared 关系,而其 create 响应从未返回过该关系;
  • Shlink 返回排序后的 tags,而 update 则回显请求中的顺序。

五个环境的端到端

该规则所影响的十个环境中,有五个被随机抽出;重新抽取,直到抽出的集合中至少有一个环境的新写入操作可获得服务:Komga、Mealie、n8n、Sentry 和 Shlink。每个环境都在其自己的 Linux VM 上,使用 #5600 的 npm pack(main 与本分支已在本地合并)重新构建;所用输入与已发布版本相同,均来自同一范围的 HAR:带 prefix-variance 的清单、导出的 bundle、smoke 任务、为 gpt-oss-120b 和 GLM-5.3-Flash 生成的检索任务,以及一个 dry-run 数据集。在写入操作可获得服务的地方,手写的写入任务以自然语言要求进行更改,并通过 data/get 根据环境状态进行评分。第一次 n8n 运行发现,一个不含数字的 workflow id 仍保持字面量;固定长度子句修复了该问题,随后重新构建了 n8n。

环境 工具(已发布 → 重新构建) 从状态获得服务(读取 / 写入) 检索 gpt-oss 检索 GLM 写入 gpt-oss 写入 GLM
Komga 42 → 46 26 / 3 12/12(之前为 11/12) 12/12(11/12) 3/4 4/4
Mealie 39 → 39 36 / 0 12/12(12/12) 12/12(12/12) – –
n8n 30 → 33 17 / 1 9/9(9/9) 9/9(9/9) 2/2 2/2
Sentry 34 → 34 26 / 3 12/12(12/12) 11/12(12/12) 2/4,重跑 0/4 4/4
Shlink 17 → 17 5 / 0 5/7,重跑 7/7 7/7(7/7) – –

所有冒烟任务均通过。偏差如下:

  • 使用 gpt-oss 的 Sentry 写入:每个失败的轮次都为 /api/0/ 段传入 id: "sentry",而该段在工具模式中被描述为 observed: 0,因此其调用指向了 /api/sentry/…;每个通过的轮次以及每个 GLM 轮次都传入了 0。所提供的工具是可用的;对一个只承载过 0 的段而言,格式规则参数会引发上述猜测。
  • 使用 gpt-oss 的 Komga 更新以及 Shlink 的首次 gpt-oss 运行:模型提供商在环境看到这些调用之前,就拒绝了模型生成的工具调用(可选查询参数为 null 和 undefined)。
  • 使用 GLM 的 Sentry qa-03:模型从未调用过 alert-rules 工具。

同样的调用也被重放到了实际应用中,这些应用由同一批脚本注入初始数据(id 不同,因此每一侧都会将自己的 id 映射为名称):

  • Komga 1.29.1,12 步中有 9 步一致:集合的创建、更新和删除及其后的读取结果都一致,只有生成的 id 不同。创建后的集合列表不会包含新集合,因为该列表保留的是已记录的成员关系;已删除集合的 404 响应会重放已记录的响应体,包括其中的路径和时间戳。
  • n8n 1.123.85,8 步中有 3 步一致:n8n 拒绝删除未归档的工作流(400),而环境会直接删除它;工作流列表重放的是已记录的响应,因此删除操作不会在其中显示;归档不被提供。对无数字工作流的读取在第一个构建中失败(状态只保存了其列表字段),在第二个构建中则一致,只是种子生成的 id 不同。

审查轮次之后

分支在提交 52c84f6f 处合并了 main;随后,每个共享位置的值都连同观察到它们的参数一起保留(每个命名规则一个 donor;字面量优先取观察到它的 donor,否则取最早出现的类似拼写),对每个 donor 的拼写只汇总一次,并且让一个观察结果形成一个定长族,正如需求所规定。两个新测试——一个混合规则位置和一个单次观察到的工作流 id——在之前的 head 上失败,在这里通过。上述门禁再次通过(domain 和 services 共 7255 个通过,另有 5 个预先存在的跳过;聚焦边界 76 个;jscpd 3.49%)。在 50 个 showcase 捕获中,带与不带 prefix-variance 的工具逐名称保持不变:69 个字面量工具被模板化,其中 25 个是写入。

第二轮审查收紧了拼写汇总的边界:字符在单次遍历中完成分类,超过 128 字符的值只进行精确比较。其测试在之前的 head 上失败;门禁再次通过(domain 和 services 7257,聚焦边界 76,jscpd 3.49%);对 50 个捕获的普查结果也再次保持不变。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 rea2/rea