embedding / OCR 的 reasoning_applies=False 无测试守护:改成 True 后全套件仍绿 #26

Closed
opened 2026-09-09 10:45:26 +08:00 by iomgaa · 1 comment
Owner

一句话

embedding.py:416 与 ocr.py:459 传的 reasoning_applies=False 没有任何测试守着——改成 True 后全套件仍绿,而 ARCHITECTURE 与 CHANGELOG 都明文承诺「embedding / OCR 路径该列恒 NULL」。

怎么发现的

2026-09-05 合并前的独立验证做了 27 个变异测试(在仓库副本里改实现、看套件红不红),24 个被杀。存活的 3 个里有 2 个是这一条(M15 / M23),第 3 个(M22,装配守卫的 effort_fallback)已在 bb9ef03 补上。

现状(2026-09-08 实测)

src/polygateway/middleware/retry.py:425   reasoning_applies=True     # chat 路径
src/polygateway/embedding.py:416          reasoning_applies=False
src/polygateway/ocr.py:459                reasoning_applies=False

reasoning_applies 是 1.3.3 给 TelemetryEmitter.emit_attempt 加的无默认值参数,用途是区分「这条路径有没有推理语义」。它无默认值这一点本身是有守卫的(tests/unit/test_telemetry.py::test_reasoning_applies_has_no_default 用 inspect.signature 断言),缺的是取值正确性的守卫。

失败场景

三条路径共用 SourceConfig 类型。一个 embedding 源若误配了 ENABLE_THINKING(该键对 embedding 无意义,但配上不报错),而 reasoning_applies 又被写成 True,那么:

  • emitter 会对失败尝试走 effective_effort(...) 回落,把 enable_thinking=True 的语法糖算成 auto;
  • 于是一次从不携带任何推理参数的 embedding 调用,在 llm_calls.reasoning_effort 列上被挂了一个 auto;
  • 下游按档位分组做压测时,这些行会混进推理调用的桶里。

这正是 tests/unit/test_telemetry.py::test_a_reasonless_path_never_records_a_tier 想防的形态——但那条用例只覆盖了 emitter 内部的分支逻辑,没有覆盖两个调用点实际传了什么。

文档承诺

  • research-wiki/ARCHITECTURE.md §7.8 遥测列口径:「embedding / OCR 两条路径没有推理语义,该列恒 NULL」
  • CHANGELOG.md 1.3.3 段「遥测:第 26 个 INSERT 字段」同款表述

承诺写了、代码是对的、没有执法点——属于典型的「今天正确,明天被人顺手改坏而无人察觉」。

修法

给两个调用点各补一条断言。可选形态:

  1. 签名/实参断言:用 inspect 或 mock 捕获 emit_attempt 的实参,断言 embedding / OCR 路径传的是 False(最直接,离线可跑);
  2. 落库断言:走一次 embedding / OCR 的遥测链路,断言 llm_calls.reasoning_effort IS NULL(更贴近承诺本身,但要起 recorder)。

第 2 种更接近「验的是承诺而不是实现细节」,若成本可接受优先它。

验收判据:把任一调用点的 False 改成 True,套件必须红。这是本 issue 的唯一验收标准——补完请用变异确认,否则补的还是假证据。

## 一句话 `embedding.py:416` 与 `ocr.py:459` 传的 `reasoning_applies=False` **没有任何测试守着**——改成 `True` 后全套件仍绿,而 ARCHITECTURE 与 CHANGELOG 都明文承诺「embedding / OCR 路径该列恒 `NULL`」。 ## 怎么发现的 2026-09-05 合并前的独立验证做了 27 个变异测试(在仓库副本里改实现、看套件红不红),24 个被杀。存活的 3 个里有 2 个是这一条(M15 / M23),第 3 个(M22,装配守卫的 `effort_fallback`)已在 `bb9ef03` 补上。 ## 现状(2026-09-08 实测) ``` src/polygateway/middleware/retry.py:425 reasoning_applies=True # chat 路径 src/polygateway/embedding.py:416 reasoning_applies=False src/polygateway/ocr.py:459 reasoning_applies=False ``` `reasoning_applies` 是 1.3.3 给 `TelemetryEmitter.emit_attempt` 加的**无默认值**参数,用途是区分「这条路径有没有推理语义」。它无默认值这一点**本身是有守卫的**(`tests/unit/test_telemetry.py::test_reasoning_applies_has_no_default` 用 `inspect.signature` 断言),缺的是**取值正确性**的守卫。 ## 失败场景 三条路径共用 `SourceConfig` 类型。一个 embedding 源若误配了 `ENABLE_THINKING`(该键对 embedding 无意义,但配上不报错),而 `reasoning_applies` 又被写成 `True`,那么: - emitter 会对失败尝试走 `effective_effort(...)` 回落,把 `enable_thinking=True` 的语法糖算成 `auto`; - 于是一次**从不携带任何推理参数**的 embedding 调用,在 `llm_calls.reasoning_effort` 列上被挂了一个 `auto`; - 下游按档位分组做压测时,这些行会混进推理调用的桶里。 这正是 `tests/unit/test_telemetry.py::test_a_reasonless_path_never_records_a_tier` 想防的形态——**但那条用例只覆盖了 emitter 内部的分支逻辑,没有覆盖两个调用点实际传了什么**。 ## 文档承诺 - `research-wiki/ARCHITECTURE.md` §7.8 遥测列口径:「embedding / OCR 两条路径没有推理语义,该列恒 `NULL`」 - `CHANGELOG.md` 1.3.3 段「遥测:第 26 个 INSERT 字段」同款表述 承诺写了、代码是对的、没有执法点——属于典型的「今天正确,明天被人顺手改坏而无人察觉」。 ## 修法 给两个调用点各补一条断言。可选形态: 1. **签名/实参断言**:用 `inspect` 或 mock 捕获 `emit_attempt` 的实参,断言 embedding / OCR 路径传的是 `False`(最直接,离线可跑); 2. **落库断言**:走一次 embedding / OCR 的遥测链路,断言 `llm_calls.reasoning_effort IS NULL`(更贴近承诺本身,但要起 recorder)。 第 2 种更接近「验的是承诺而不是实现细节」,若成本可接受优先它。 **验收判据**:把任一调用点的 `False` 改成 `True`,套件必须红。这是本 issue 的唯一验收标准——补完请用变异确认,否则补的还是假证据。
Author
Owner

真实 GatewayClient→治理→emitter→recorder 路径覆盖 embedding、OCR text/layout 成败 NULL,临时 SQLite 持久化锚点及 chat 阳性防止全 NULL 假绿。已有独立核验的 embedding False→True、OCR两入口 False→True、chat True→False、移除 applies 短路变异均被目标断言杀死并还原通过;本轮按复用原则不重复制造相同证据。

发布:v1.3.4,main/tag 提交 af57f93adce24b43fd10b6d8e1281ab8ee43c0a8。合并后 make lint 通过;make test:1518 passed / 23 skipped / 108 deselected,95%覆盖率;定向 M2.5/M2.7 AUTO:2 passed(各5轮,并发1);Redis时间语义:18 passed。wheel/sdist 从 registry 独立下载,散列与构建一致,解包及独立 target 安装行为、README元数据通过;Release正文、包页面正文和仓库链接已亲查。

2026-09-09 用户批准不补全模型矩阵:embedding 503仍FAIL、claude-opus-5开启命题仍FAIL,UNKNOWN/身份不足/不可达/缺轮/缺下游现行配置证据保持例外,不改成PASS,不宣称三项目已完成迁移。

Release · 包页面 · 验证与例外记录
原始本轮日志:tests/outputs/134/publish-20260909/;既有红绿与独立审查见上述验证记录。

真实 GatewayClient→治理→emitter→recorder 路径覆盖 embedding、OCR text/layout 成败 NULL,临时 SQLite 持久化锚点及 chat 阳性防止全 NULL 假绿。已有独立核验的 embedding False→True、OCR两入口 False→True、chat True→False、移除 applies 短路变异均被目标断言杀死并还原通过;本轮按复用原则不重复制造相同证据。 发布:v1.3.4,main/tag 提交 af57f93adce24b43fd10b6d8e1281ab8ee43c0a8。合并后 make lint 通过;make test:1518 passed / 23 skipped / 108 deselected,95%覆盖率;定向 M2.5/M2.7 AUTO:2 passed(各5轮,并发1);Redis时间语义:18 passed。wheel/sdist 从 registry 独立下载,散列与构建一致,解包及独立 target 安装行为、README元数据通过;Release正文、包页面正文和仓库链接已亲查。 2026-09-09 用户批准不补全模型矩阵:embedding 503仍FAIL、claude-opus-5开启命题仍FAIL,UNKNOWN/身份不足/不可达/缺轮/缺下游现行配置证据保持例外,不改成PASS,不宣称三项目已完成迁移。 [Release](https://gitea.iomgaa.online/iomgaa/PolyGateway/releases/tag/v1.3.4) · [包页面](https://gitea.iomgaa.online/iomgaa/-/packages/pypi/polygateway/1.3.4) · [验证与例外记录](https://gitea.iomgaa.online/iomgaa/PolyGateway/src/tag/v1.3.4/research-wiki/findings/2026-09-09-134-thinking-contracts-validation.md) 原始本轮日志:tests/outputs/134/publish-20260909/;既有红绿与独立审查见上述验证记录。
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: iomgaa/PolyGateway#26