Skip to content

fix(dimensions): 修硬编码判定自相矛盾 + 命名口味边界;GT 扩到 25 条 - #19

Open
Luo-root wants to merge 2 commits into
mainfrom
docs/eval-caliber
Open

Luo-root wants to merge 2 commits into
mainfrom
docs/eval-caliber

Conversation

@Luo-root

Copy link
Copy Markdown
Owner

这个 PR 修什么

首轮评测实测暴露出来的三处口径问题,全部有源码或实测证据支撑。其中 references/dimensions.md 改动了「成立条件 / 不算」——按 evals/runbook.md 的规定,这类改动必须重跑评测验证,所以这个 PR 合入后需要重跑一轮。

问题 票 改在哪
硬编码维度的「算」与「不算」两句话互相打架 #16 references/dimensions.md 第 5 维
命名/分包口味这条不报边界没有可操作判据,2/3 轮报成了 P2 缺陷 #17 references/dimensions.md 第 4 维
ground truth 的 G4 判定错了;另漏了 13 条真缺陷 #15 evals/ground-truth.md + evals/rubric.md

一、硬编码维度:细则自己给了两个互斥答案

references/dimensions.md 第 5 维原本这么写:

  • 算:它必须随环境/租户/调用方/数据规模/版本变化……
  • 不算:真不变量(协议固定值、7 天),已命名、已注释、只有一个使用者。

refundWindow = 24 * time.Hour 正卡在中间:它是业务政策值(业务改成 7 天就得跟着改 → 按「算」条款该报),但它已命名、已注释、单一使用者(→ 按「不算」条款不该报)。

实测后果:B、C 两轮全量审查都判了「硬编码:无发现」,而且明确引用细则原文来支撑:

  • B 轮:「唯一的业务常量 refundWindow(refund.go:11)已命名、有注释、只服务一个规则(真不变量)」
  • C 轮:「refundWindow(已命名常量 + 已注释 + 单一使用者,按细则不算)」

模型没做错,是细则自己有两个答案。 根源是「7 天」这个例子——7 天退款窗口和 24 小时退款窗口是同一类东西,却被写进了「真不变量」。

改法:把两类值分开,并给一条一句话判据。

协议固定值 业务政策值
例子 单位换算 100、HTTP 状态码 退款窗口、账期、免费额度、保留时长
改了会怎样 改了就是 bug 只是业务口径变了
算不算 不算 算

判据一句话:改了会出错 → 不算;改了只是口径变了 → 算。

业务政策值即使已命名、已注释、单一使用者也要报,但按「需要变化的边界」选最小一档(命名常量 < 函数参数 < 配置项 < 运行时发现),不一律上配置、也不一律上 P2。

二、命名/分包口味:抽象规则缺可操作判据

原来只有一个标签:「纯格式、命名口味、import 顺序、主观分层偏好」。

模型看到的是一条抽象规则 + 一个具体事实(「两个包同名、目录名不一致」),事实看起来有后果(import 要别名、godoc 混在一起),于是按文档维度的成立条件报了。

补了三条可判定的判据(编译器会不会出错 / 项目里有没有相反惯例 / 能不能不改),并写明:真要提只能进「需要你拍板」,不能进「必须修 / 建议修」。同时补了一句反向提醒——别因为这条把真正的文档缺陷放过去(godoc 与实现不符、注释说反返回值顺序,照报)。

三、ground truth:G4 判定错了,另漏 13 条真缺陷

G4 判定错的:源码那句承诺有限定语——

// Checkout is read-only with respect to the order store: it never mutates
// orders and never writes back to the database.

限定语是「read-only with respect to the order store」。c.Processed / c.Stats 是 Checkout 自己的字段,不是订单存储;模块里也没有数据库可供违反。我当初把「有副作用」等同于「违反 read-only 承诺」了。

实测佐证:三轮里两轮明确判定该承诺成立并给了推理(A:「读完 Run 全函数确认只读 orders 的副本,没有改订单、没有回写」;B:「逐行读 checkout.go:67-78 确认无写操作」)。

修法:G4 改成另一个真问题——承诺提到的「订单存储 / 数据库」在这个模块里根本不存在,属于该进拍板的文档问题。同时把原判定写进「不该报」清单,附理由。

另补 13 条真缺陷(G13–G25):三路合计发现,全部可复核。最值得注意的几条:

  • G13 ExpiresAt 用查询时刻 +24h,签发时刻根本没存(issued 只存金额)→ 退款窗口永远关不上
  • G14 Issue 收「元」、IssuedCents 返「分」→ 把结算总额传进去就是 100 倍退款
  • G15 0 元退款被记成「已退款」→ 之后任何真退款静默 no-op
  • G17 Stats 共享指针 + 非原子自增 → 并发丢计数 + data race

GT 从 12 条扩到 25 条,rubric.md 的分母同步改(命中/归类/表达 12 → 25,raw 量级 50+ → 100+)。


口径与后续

  • evals/baseline.md 里的分数是首轮 12 条口径下的结果,与新口径不可直接比较。 baseline.md 顶部已加口径提示,旧记录不覆盖——它是「当时按当时的标准答案跑出来的结果」,属历史事实。
  • 合入后需要按新口径重跑一轮评测(改了 dimensions.md 的成立条件 → runbook 规定必须跑),新基线追加到 baseline.md,不覆盖旧节。
  • evals/runbook.md 的归档段补了「存哪、怎么追加、口径变了怎么办」。
  • G13 特意注明:判成 bug 或判成拍板都算命中(这个模块没有调用方,「该不该有退款窗口」本身就是业务问题)。

验证

  • node tools/lint-skill.mjs . 通过。
  • 全仓扫描「内置 / 别的工具 / 第二个工具」:零命中。
  • 本 PR 改了 skill 执行文件(references/dimensions.md)→ 触发 runbook 的「必须跑评测」,重跑是合入后的必要动作。

关联 #15、#16、#17。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant