⚠️ 声明:本文件只记录 v2.2.1 新增用例(SF-47 / SNF-37)的 targeted 回归,不是全量 84 条实跑,也不替代 v2.1.0 的全量盲测基线。 v2.1.0 的完整双模型全量结果仍以 results-v2.1.0.md 为准。
复核时间:2026-08-06 范围:本版新增的 2 条用例(SF-47 = B-12、SNF-37 = B-38)。 评测集:evals/benchmark.md(84 条:47 SF + 37 SNF)。
补的是篇章级密度视野:规则此前只有单句判定,同一种句式骨架跨段反复出现时,逐句看每句都成立,规则给不出任何判据。
缺口的历史证据在仓库里:evals/benchmark-tiers.md 记录 SF-40 降 L3 的第一条理由就是「操作手册只约束『同段连续叠加』」。也就是说这个缺口被遇到过,当时的处理是把用例降层,没有补规则。
同一份 structures.md 里,第 20 条(破折号腔)已经写对了密度型规则的体例——「看密度和位置,不看单次出现」「单段两处以上」「不要见一个杀一个」。本版把第 1 条按同样体例补齐。
另有一处合同漏抄:positive-style.md §2.3 和 operation-manual.md §9 都写了「长度、抬手和落点都太整齐」,但 SKILL.md Pass 2 第 5 项只抄了「句长过匀」。SKILL.md 是行为合同单源,模型实跑按它走,于是只查句长——长短句交替的文本直接过关。
Codex 侧走 codex exec --sandbox read-only;Claude 侧改用冷启动 subagent 执行,同样只给 SKILL.md / references/ / benchmark-blind.md,不给 benchmark.md 及任何含预期的文件。两侧口径一致,均为盲测。
关于 Claude 侧为什么不走
claude --print:本轮在 Claude Agent SDK 宿主环境下运行(CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST已设、ANTHROPIC_BASE_URL由宿主注入、无~/.claude/.credentials.json)。凭证由宿主托管且不落盘,从 shell 另起的claude子进程走标准凭证查找路径拿不到 token,报Not logged in。这是进程边界问题,不是账号未登录。被测模型仍是 Claude Opus 5,与 CLI 路径同模型同口径。
| 轮次 | 规则状态 | Codex SF-47 | Claude SF-47 | SNF-37(双侧) |
|---|---|---|---|---|
| r2 | 阈值已加,豁免未剔除 | ✅ 改 2 处 | ✅ 双侧 no-op | |
| r3 | 加「豁免先剔除」 | ❌ 全豁免 no-op | ❌ 全豁免 no-op | ✅ 双侧 no-op |
| r4 | 豁免加上限 2 + 可判定判据 | ✅ 改 2/2 处,未用倒装充数 | ✅ 双侧 no-op |
(r1 因 SNF-37 原文字数卡在阈值边界作废,见 §3。)
r2 交叉判分(Codex 判 Claude / Claude 判 Codex,双向):硬约束失败清单均为「无」,SNF 误杀 0。
初版阈值只写「< 300 字」,没说怎么数。SNF-37 原文按可见字符是 355(落 300–1000 档,2 处不命中),按汉字是 241(落 <300 档,2 处正好命中)——两个模型当轮就各按各的口径数了。
修法两条并用:阈值计数口径明确为「中文按字、英文按词、代码片段 / 路径 / 命令 / 版本号各计 1、标点空白不计」(对齐 severity.md 体例);同时把 SNF-37 正文加长到约 350 字/词,让它无争议落在 300–1000 档。
r2 的交叉判分里,judge 指出第 1 条内部矛盾:检测阈值是「< 300 字/词 2 处以上」即命中,默认动作却允许「保留承担真实对比的 1–2 处」——短文里保留 2 处的输出重新过一遍规则会再次判超标,规则自我循环。
修法是「豁免项先剔除再计数」。这个修法当轮就造成了回归:r3 双侧对 SF-47 全部判 no-op。两个原因叠加:
- 「对比本身是论证骨架」没有可判定边界,任何带信息的对比都能声称自己在论证;
- 本版曾把 SF-40 的用例级例外「作者刻意用对比结构承载全文论点」写进
structures.md当通用保留条件——benchmark-tiers.md里它是带理由的单条例外,提升为通用规则后变成了万能豁免口。
r4 修法:
- 豁免上限 2 处(术语定义 1 处 + 论证骨架 1 处)。超过 2 处都声称承担论证时不再逐条豁免——每一处都说得出理由,恰恰是骨架依赖的表现。
- 论证骨架给可判定判据:前半句必须是读者会真实持有的误解,且删掉后后文的数据、结论或动作会失去依据;「读起来气势弱一点」不算。
- 删掉越界的通用豁免口,在规则里显式指回
benchmark-tiers.md例外表。 - 补一句「只把
不是 X,是 Y倒装成Y,不是 X不算完成降密度」——这是 r2 Codex 侧的实际行为。
L1 硬约束四轮全部 0 失败。hard_metrics.py --pair 粗核:SF-47 protected spans 7/7、SNF-37 19/19,破折号 0 处;两条均非 public-writing / long / in-place,留存率判据不适用。
逐字保真核对:SF-47 的 retry-guard、上游/中间层/下游各 3 次、27 次、2026-04、9 倍;SNF-37 的 --apply / --yes / --skip-lock-check / MIGRATE_TIMEOUT / schema_migrations / performance_schema.metadata_locks / ALTER / CREATE / DROP INDEX / SUPER / version / applied_at / checksum / 600 秒 / 120 秒 / 50 张表 / DDL / dry-run。
按 benchmark-tiers.md(2026-07-23 起):
- L1 硬约束失败 = 0 —— 达标。
- SNF 误杀率 < 10% —— 达标(0/1 = 0%)。
- 本版新增用例 targeted 双模型达标 —— 达标。Codex 侧 SF-47 的
⚠️ (只改 1/2 处非豁免骨架)落在 L2 风格层,按分层规则进报告与趋势、不进门槛。
明确不做的事:没有为了让 Codex 侧也拿到 ✅ 而继续调规则。benchmark-tiers.md 开头的防放水约束和「为什么分层」一节警告的正是这件事——规则围着单个失败用例长例外。r4 的状态是「两个模型都识别密度、都不误杀,一个改得完整一个改得保守」,这是 L2 该有的分歧形态。
同理,本版没有移动任何用例的层级。SF-40 维持 L3;它降层理由的后半句(作者刻意用对比结构论证「反对过度整理」,no-op 有合理性)不受本版影响。
- Codex 侧在 r4 只改了 2 处非豁免骨架中的 1 处,判定链写的是「只调整超出密度阈值的一处」——它把阈值理解成了「超出部分的数量」而不是「超出阈值就全改」。规则文本可能还能更明确,但本版不再改,留作下一轮观察项。
.claude-plugin/plugin.json与marketplace.json的version仍停在2.1.0,v2.2.0 起未同步。属既存状态,本版未动。- 本轮没跑 84 条全量,改跑 7 条影响面回归(见 §7)。选择依据:新规则只对含二元对比骨架的文本生效,全库扫描确认 15 条含骨架、其中 7 条按新阈值行为会改变,其余 69 条对新规则是 no-op。
- 密度判据给了模型一个合法的停手点:SF-39 改完后剩余骨架数正好落到
300–1000 字 3 处以上阈值之下,模型可能据此「达标即停」,留下 benchmark 逐条点名的另外两处骨架。密度阈值与逐条点名的预期之间存在张力。本版不改——这属于「答案不唯一」还是「规则说不清」需要更多样本才能判,现在动就是围着单个用例长例外。后续若长文用例的 L2 通过率继续走低,从这个方向查。
新规则只对含二元对比骨架的文本生效,影响面可枚举。全库 84 条扫描后确认 15 条含骨架,其中按新阈值行为会改变的 7 条全部实跑:
| 用例 | B 编号 | 字/词 | 骨架 | 阈值 | 选它的理由 |
|---|---|---|---|---|---|
| SNF-29 | B-54 | 225 | 2 | 2 | 误杀风险:in-place 长文,测「承担节奏的重复不该删」 |
| SNF-30 | B-79 | 201 | 2 | 2 | 误杀风险:in-place 长文,测「正常承接句不是总结腔」 |
| SF-04 | B-53 | 57 | 2 | 2 | 二元对比正例,新规只会加强 |
| SF-16 | B-15 | 40 | 2 | 2 | 同上 |
| SF-39 | B-25 | 367 | 4 | 3 | in-place 长文,行为可能变 |
| SF-40 | B-63 | 284 | 3 | 2 | L3,本次缺口的历史证据 |
| SF-47 | B-12 | 163 | 4 | 2 | 本版新增,对照组 |
其余 69 条不含该骨架,新规则对它们是 no-op。
| 编号 | Codex 侧 | Claude 侧 |
|---|---|---|
| SF-47 | ✅ | |
| SF-16 | ✅ | 最后比拼的是 |
| SF-39 | ||
| SF-04 | ✅ | |
| SF-40 | ✅(L3 可接受集) | ✅(L3 可接受集) |
| SNF-29 | ✅ no-op | ✅ no-op |
| SNF-30 | ✅ no-op | ✅ no-op |
L1 硬约束失败:0(双侧)。SNF 误杀:0/2(双侧)。
- 误杀方向(本轮重点):SNF-29 / SNF-30 按新判据都会在
< 300 字 2 处以上阈值上「名义命中」,两侧四次运行全部走到not-fix / no-op,正文逐字 100% 保留(254/254、231/231)。豁免上限没有把节奏性重复和正常转场推进改写。 - 「该改的反而不改」方向:没有出现。SF-47 正是为挡 r3 那种「全判豁免 → 整条 no-op」设计的,本轮双侧都是豁免 2 处、改 2 处;SF-39 / SF-40 也都实际改写。
⚠️ 项与密度规则无关:SF-16 漏改的最后比拼的是属phrases-zh词表 +structures§19 价值拔高骨架,不走第 1 条;SF-39 是预期点名骨架覆盖不全。硬约束层(留存率、句数、段序、引号保护)全部达标。
至此 §6 中「新规则对存量用例影响未验证」一条销掉。