session-mechanism: 修复钩子静默失效 + 3 处判据缺陷;禁「变相征询」

1) stop-dialog-guard: session_budget() 早退路径返回 2 值、末尾返回 3 值,调用方按 3 值解包
   ⇒ transcript > 64 MiB 时每轮 ValueError。因 fail-open(异常仍 exit 0),
   宿主零报错、install.py --verify 只判 rc=0 ⇒ 假绿;实测 86 条 EXCEPTION,
   死掉的是整条(水位/收口、接续机制起点、预算告警、门禁自检、路径自检)。

2) session-rules-check 三处判据:
   · hook_reg  按旧文件名找 ⇒ 合并成 prompt-guards.py 后每轮假红 ⇒ 改为一组可接受名
   · snap_sync 拿 mtime 当内容判据 ⇒ 连续 4 天假红 ⇒ 改为复用抽取器本体比对内容
               (变异对照:截断快照能报 fail,非恒绿)
   · mem_ptr   只查全局技能根 ⇒ 工作区自带技能被判悬空 ⇒ 改查「全局 ∪ 工作区」

3) pitfalls 新增 P0-95(改判据必须重跑变异对照;fail-open + 只看 rc=0 = 假绿温床)

4) 回复排版核心块新增「变相征询同样禁止」(先只报不动/等你发话/我倾向X你看呢
   这类不带选项的待定清单,一律按待拍板项写:问题+说明+各候选优缺点+倾向)
This commit is contained in:
admin committed 2026-10-06 22:27:03 +08:00
1 parent 19101acd65
commit 64dd82073b
21 files changed
+8444 -4523

No files matched your search

@@ -432,12 +432,28 @@ def _set_level(root, sid, lv):
def session_budget(path):
"""返回 (当前上下文 token, 工具调用累计次数);读不到返回 (None, None)。"""
"""返回 (当前上下文 token, 工具调用累计次数, 上一次上下文 token);读不到返回三元 None。
🔴🔴 2026-10-06 修 **本函数返回元组长度不一致**(真缺陷 · 已实测坐实):
原先**两条早退路径只返回 2 值**(transcript > 64 MiB / `getsize` 抛 OSError),
而末尾两条返回 **3 值**、调用方 `toks, ncalls, prev = session_budget(tp)`(第 611 行)
也按 **3 值**解包 ⇒ 只要 transcript **超 64 MiB**、或文件不在,
**每轮必抛 `ValueError: not enough values to unpack (expected 3, got 2)`**。
后果(比报错难查得多):本钩子是 **fail-open**(异常仍 `sys.exit(0)`)
⇒ 宿主侧**看不到任何异常**,`install.py --verify` 只判 `rc=0` ⇒ 判它 **"ok"(假绿)**;
而实际失效的是**这一整条**:水位与收口 / 接续机制起点 / 预算告警 / 门禁自检 / 路径自检。
证据:`<WS>/.workbuddy/stop-dialog-guard.log` **86 条 EXCEPTION**(首条 2026-10-06 05:09:26),
且**每轮复现**——因为本会话 transcript 已达 **192.8 MB**(>64 MiB 阈值)⇒ 命中的正是第 437 行那条早退。
⇒ 判据:**同一函数的所有 return 必须同长**;“防护性早退”最容易漏掉这一条。
"""
try:
if os.path.getsize(path) > 64 * 1024 * 1024:
return None, None
return None, None, None
except OSError:
return None, None
return None, None, None
last_in, n_calls, prev_in = None, 0, None
try:
with io.open(path, encoding='utf-8', errors='replace') as f: