决策快照补unlock_level打点,收敛drive-tick重复计算(issue #140) #147

Merged
Yushu merged 1 commit from feat/140-unlock-level-instrumentation into main 2026-08-17 07:42:16 +00:00
Member

Closes #140

做了什么

观察票(issue #133 让 drive-tick/私聊即刻追问成了 level1_score 真实消费者后,issue #112 "渐进解锁缩放消费者集合为空"的论证前提不再完全成立,但要不要补一道类似 tier-2 的独立解锁门槛需要真实数据支撑)——本片不做任何裁决行为改动,只把判断需要的数据存下来。

一、决策快照补 unlock_level 字段(纯打点)GateEvaluationgating.py)、GateSnapshotdecision_snapshot.py)、gate_snapshot_of() 搬运函数、DecisionSnapshotModel 列定义 + 两处行映射(写入/读出),六处全部补上。记的是 evaluate_gate() 两条返回路径(级一未过早退 / 完整走完)各自实际用于预算缩放的那个 unlock_level 值,不是重新算一次。

二、顺手收敛 entry_drive_tick.py 里同一次评估 unlock_level 被算两次的问题:门控调用之后才独立算一次(供自发目标/熟人重连提示用)——上提到门控调用之前,通过 _evaluate_unified_gate 既有的 unlock_level= 覆盖参数传入(同 entry_reactive._debounced_flush 既有先例),后面消费点复用同一个值。

验证

  • 新增测试:test_gating_storage.py::TestEvaluateGateUnlockLevelInstrumentation(两条返回路径都记对值)、test_decision_snapshot_storage.py::TestGateSnapshotOf(搬运函数不漏字段)、往返测试补 unlock_level 断言、test_drive_tick_e2e.py 新增去重回归测试(同时 monkeypatch entry_drive_tick/gate_pipeline 两个模块各自持有的 compute_unlock_inputs 引用,防止只堵一边测不出"漏传覆盖参数导致内部兜底重新计算"这类退化)。
  • GateSnapshot/GateEvaluation 都没给新字段设默认值(沿用两个类既有的 no-default 惯例),因此另外 3 处直接构造 GateSnapshot(...) 的既有测试 fixture(test_why_commands.py/test_explain.py/test_decision_snapshot_storage.py)补了必填参数——机械传导,未改动任何 verdict/passed_level1 等裁决类断言本身。
  • 变异测试 5/5:GateEvaluation 两处构造点硬编码值、gate_snapshot_of() 硬编码、存储写入路径硬编码、存储读出路径硬编码、entry_drive_tick.py 重复计算复原(含"只删覆盖参数、留着提前算但不传"这种更隐蔽的变体)——均被对应测试捕获。
  • 全量测试 1878 passed,ruff 通过,ty 与既有基线一致(47 条,均非本片改动文件)。
  • 两轴 review(Standards + Spec,sonnet,含对抗式 Verify):1 条 MEDIUM 发现 CONFIRMED 并已修复——gate_pipeline.py 共用入口的 docstring 未同步,原文点名"Drive Tick 等其它调用方不受影响"已经不准确(本片已经让 Drive Tick 也改成显式传入),改为点名仍走内部自读兜底分支的两个调用方(群聊即刻追问 _run_group_followup_check、tier-2 环境信号)。

不做的事(按 AC)

不新建任何门槛机制,不碰 progressive_unlock_scale/gate_threshold_base 现有裁决逻辑;不产出任何分析/报表;不涉及 docs 分支改动(ADR-0011/0014 更新节的补录属另一批次)。

Closes #140 ## 做了什么 观察票(issue #133 让 drive-tick/私聊即刻追问成了 `level1_score` 真实消费者后,issue #112 "渐进解锁缩放消费者集合为空"的论证前提不再完全成立,但要不要补一道类似 tier-2 的独立解锁门槛需要真实数据支撑)——本片不做任何裁决行为改动,只把判断需要的数据存下来。 **一、决策快照补 `unlock_level` 字段(纯打点)**:`GateEvaluation`(`gating.py`)、`GateSnapshot`(`decision_snapshot.py`)、`gate_snapshot_of()` 搬运函数、`DecisionSnapshotModel` 列定义 + 两处行映射(写入/读出),六处全部补上。记的是 `evaluate_gate()` 两条返回路径(级一未过早退 / 完整走完)各自实际用于预算缩放的那个 `unlock_level` 值,不是重新算一次。 **二、顺手收敛 `entry_drive_tick.py` 里同一次评估 `unlock_level` 被算两次的问题**:门控调用之后才独立算一次(供自发目标/熟人重连提示用)——上提到门控调用之前,通过 `_evaluate_unified_gate` 既有的 `unlock_level=` 覆盖参数传入(同 `entry_reactive._debounced_flush` 既有先例),后面消费点复用同一个值。 ## 验证 - 新增测试:`test_gating_storage.py::TestEvaluateGateUnlockLevelInstrumentation`(两条返回路径都记对值)、`test_decision_snapshot_storage.py::TestGateSnapshotOf`(搬运函数不漏字段)、往返测试补 `unlock_level` 断言、`test_drive_tick_e2e.py` 新增去重回归测试(同时 monkeypatch `entry_drive_tick`/`gate_pipeline` 两个模块各自持有的 `compute_unlock_inputs` 引用,防止只堵一边测不出"漏传覆盖参数导致内部兜底重新计算"这类退化)。 - `GateSnapshot`/`GateEvaluation` 都没给新字段设默认值(沿用两个类既有的 no-default 惯例),因此另外 3 处直接构造 `GateSnapshot(...)` 的既有测试 fixture(`test_why_commands.py`/`test_explain.py`/`test_decision_snapshot_storage.py`)补了必填参数——机械传导,未改动任何 verdict/passed_level1 等裁决类断言本身。 - 变异测试 5/5:`GateEvaluation` 两处构造点硬编码值、`gate_snapshot_of()` 硬编码、存储写入路径硬编码、存储读出路径硬编码、`entry_drive_tick.py` 重复计算复原(含"只删覆盖参数、留着提前算但不传"这种更隐蔽的变体)——均被对应测试捕获。 - 全量测试 1878 passed,ruff 通过,ty 与既有基线一致(47 条,均非本片改动文件)。 - 两轴 review(Standards + Spec,sonnet,含对抗式 Verify):1 条 MEDIUM 发现 CONFIRMED 并已修复——`gate_pipeline.py` 共用入口的 docstring 未同步,原文点名"Drive Tick 等其它调用方不受影响"已经不准确(本片已经让 Drive Tick 也改成显式传入),改为点名仍走内部自读兜底分支的两个调用方(群聊即刻追问 `_run_group_followup_check`、tier-2 环境信号)。 ## 不做的事(按 AC) 不新建任何门槛机制,不碰 `progressive_unlock_scale`/`gate_threshold_base` 现有裁决逻辑;不产出任何分析/报表;不涉及 `docs` 分支改动(ADR-0011/0014 更新节的补录属另一批次)。
GateEvaluation/GateSnapshot/gate_snapshot_of/DecisionSnapshotModel四处
补unlock_level字段,记录该次评估实际用于预算缩放的渐进解锁档位,纯打点
不改任何裁决逻辑——为后续判断drive-tick/私聊即刻追问要不要补独立解锁
门槛积累真实数据(issue #133让这两条路径成为level1_score真实消费者后,
issue #112"消费者集合为空"的论证前提不再成立)。

顺手收敛entry_drive_tick.py里同一次评估unlock_level被算两次的问题:
提到门控调用前算一次,通过既有的unlock_level=覆盖参数传入,同entry_
reactive._debounced_flush既有先例。

两轴review发现gate_pipeline.py共用入口的docstring未同步——原文点名
"Drive Tick 不受影响"已经不准确,改为点名仍走内部自读分支的两个调用方
(群聊即刻追问/tier-2环境信号)。
Yushu merged commit b83cd7f9a2 into main 2026-08-17 07:42:16 +00:00
Yushu deleted branch feat/140-unlock-level-instrumentation 2026-08-17 07:42:18 +00:00
Sign in to join this conversation.
No description provided.