diff --git a/WORKMEMORY/INDEX.md b/WORKMEMORY/INDEX.md index 0fb6090f..fc5c2e4d 100644 --- a/WORKMEMORY/INDEX.md +++ b/WORKMEMORY/INDEX.md @@ -35,6 +35,7 @@ | ADR-0023 交互层「验证驱动 agent 循环」Task 0~6(Go 门禁三红灯 / LLM 收口 / 循环内核 / 工具白名单 / 契约+前端) | `work.log`(10-14~10-15 段)· 计划正本 `docs/plans/2026-10-14-interactive-agent-loop.md` · PR #136 | ## Active handoffs +- 2026-10-15 → [`handoff_judge-gaming-experiment.md`](handoff_judge-gaming-experiment.md)(to: any · role: IMPLEMENT/TEST/VERIFY · status: open)— §4.3 第 8 条对照实验:主实验(N=20)全量 60 局真跑完成,原始输出与评估报告已落盘,待 ADR §4.3 回写签批与 PR #139 收尾 - 2026-10-14 → [`handoff_interactive-agent-loop.md`](handoff_interactive-agent-loop.md)(to: any · role: IMPLEMENT/TEST/VERIFY · **status: closed 2026-10-15**)— ADR-0023 交互层 agent 循环:Task 3~6 + CI 半 + 开 PR 均已交付(PR #136);剩余待办(真机点检 / ADR §6 回写 / Unknown A)见其「响应」节 - 2026-10-14 → [`handoff_no-console-feedback-gaps.md`](handoff_no-console-feedback-gaps.md)(to: any · role: VERIFY/TEST · status: open)— 真机双击验收 + digest 归一历史 header diff --git a/WORKMEMORY/handoff_judge-gaming-experiment.md b/WORKMEMORY/handoff_judge-gaming-experiment.md new file mode 100644 index 00000000..00731d3f --- /dev/null +++ b/WORKMEMORY/handoff_judge-gaming-experiment.md @@ -0,0 +1,219 @@ +--- +to: any +from: codebuddy (GLM-5.3-Flash) +created: 2026-10-15 +role: IMPLEMENT | TEST | VERIFY +required_capability: python-3.11 / spaCy(de_core_news_sm) / 真实 DEEPSEEK_API_KEY(Task 5/6 才用) +status: open +--- + +# 交接包:§4.3 第 8 条对照实验(浅裁判是否真被模型针对)—— Task 1 已完成待验收,Task 2~6 待做 + +## 一、任务上下文(60 秒读完) + +- **判据原文**(ADR-0023 §4.3):「浅裁判 + 循环 = 奖励黑客:模型会学会『通过检查』而非『写得更好』」⇒ 实验必须能分别证伪 **P1(奖励黑客)/ P2(真变好)**。 +- **计划正本**:`docs/plans/2026-10-15-judge-gaming-experiment.md`(6 任务,台账 **0/6,Task-1 IN_PROGRESS**)。 +- **设计正本**:`docs/specs/2026-10-15-judge-gaming-control-experiment-design.md`(已按 `AGENT-EVALUATION-HARNESS` §1/§3 与 `AGENT-CONDUCT` §10.2 修正:**判决量只有一个 = held-out 种子错误的确定性回收率 `R_uncovered`**;LLM 盲评是**辅助信号、不进判决**;报告必须带 Token 成本 + p50/p95 延迟 + 平均轮数)。 +- **用户已拍板(2026-10-15)**: + 1. 测**现状形态**:实测发现 `polish_loop` **不把裁判结论回灌模型**(`messages.append` 站点清单见设计稿"仪器 A"修订段),模型只能主动调 `writing_check` 自查 ⇒ 本实验测的就是这个形态;**「裁判结论回灌(verifier-in-the-loop)」登记为下一个子计划**(产品能力变更,不只为了实验)。 + 2. 种子 = **每篇恰好 1 处「信号」注入**(语法族、被生产分流计数 ⇒ 该篇 `v_0 == 1`)+ **≥3 处 held-out 探针**(判决量分子)。**判决只算 probe,signal 只为触发迭代**。 + 3. 盲评 rater = 辅助信号。 +- **密钥**:`.env` 已配 `DEEPSEEK_API_KEY`(**已被 gitignore 且未跟踪** ✓)。harness 只经 `delector.server.load_env()` 载入(编排者实测:载入后 `os.environ` 与 `get_effective_api_key()` 均非空)。**MUST NOT 打印/落盘/提交 key** —— 输出与报告里只允许布尔或长度。 + +## 二、已完成(含证据) + +- **Task 1 代码完成(⚠️ 待 CRV 验收 + 变异自证补证,见"风险")**:`delector/data/a1_seed_errors.py` + `tests/test_a1_seed_errors_data.py`(**88 passed**)。接口:`SeedCase/Injection(含 kind: "signal"|"probe")` + `SEED_CASES`(**20 篇** = 10 官方书信范文反向注入 + 10 篇 `corpus_dict.OFFICIAL_CORPUS` 非书信课文逐字复制后注入)+ `ERROR_CLASSES`(恰好五类 held-out:nebensatz_wortstellung/artikel_genus/verb_kongruenz/praeposition_kollokation/nomen_grossschreibung)。 +- **编排者已逐篇实测(物理证据,替代死亡 maker 的报告)**:20/20 篇 `sig=1 / probe≥3 / 生产分流 v0=1`(signal 的 rule 分布:kasus×9 / artikel×8 / praeposition×3);ruff 全绿;`mypy --strict delector` 68 files 0;CRLF lone_LF=0。 +- **测试断言三层**:接口层(五类名/20 篇/两类各≥10/frozen+slots)· 字符串层(wrong/right 计数复算 + **双向回放** text↔clean 差异恰好是注入)· held-out 层(真实 nlp 三重差分:rule 计数多重集相等 + span 不落 wrong 区间 + 逐处回退后仍相等)+ **信号层**(每篇恰 1 signal + 生产分流 v0==1 + probe 不进计数 + 区间不重叠)。检测器 `error_type` 集合**从源码现读**(≥6 下限防正则失效假绿)。 +- **计划/设计稿的"信号注入"修订**已落盘(本包一起提交)。 +- **沉淀已完成**(99-Inbox 两张):① `2026-10-15-规则引擎硬门必须按「类」覆盖正样本…`(含两条既有规则的新证据实例:自动化接线三证 / UNVERIFIED 逐条核销);② `2026-10-15-bash-standards-§5.3-缺的一条:嵌入的-ascii-双引号…`。 + +## 三、未完成与下一步(按序) + +1. **⏳ Task 1 收尾**:a) **变异自证补证**(上轮 maker 死于报告前,未跑):① 把某篇 signal 换成 held-out 类 ⇒ "信号真被计数"用例红;② 删某篇 signal ⇒ "恰好 1 处"红;③ 把某篇 probe 换成可计数错误 ⇒ held-out 用例红。b) **CRV 验收**(把上面的逐篇 v0 表 + 88 passed 作为证据带上)。c) 原子提交(两新文件 + 计划/设计稿修订一起)。 +2. **⏳ Task 2**:三臂 harness 骨架(`tools/bench_judge_gaming.py` + 测试)—— A1 `max_turns=1`;A2 `max_turns=3` 且 `violations_of` 恒返回**同一条固定违规**(迫使迭代、无方向);A3 = 生产分流。`--dry-run`(stub chat)零 Key 可跑;退出码 0/1/2 照 `tools/bench_judge_fp.py` 惯例。⚠️ 密钥只经 `load_env()`,任何输出不得带 key。 +3. **⏳ Task 3**:测量与记账 —— `score_uncovered`(**只算 probe**)/ `score_judge_violations` / `detect_new_errors` / `summarize`(每臂 `R_judge`/`R_uncovered`/回退率/新增错误/Token/p50/p95/平均轮数)+ `Report.judgement_basis="uncovered_seed_recovery"`(钉"判决只用确定性真值")。 +4. **⏳ Task 4**:盲评 rater(`tools/bench_judge_rater.py`)—— 顺序由 `order_seed` 决定、rubric 无臂标签、结果只进 `report["auxiliary"]`(有测试断言判决字段未变);`--dry-run` 跳过。 +5. **⏳ Task 5(HITL)**:pilot N=5 真跑(先交用户确认花费口径)→ 按实测方差**固定阈值回写设计稿**。 +6. **⏳ Task 6(HITL)**:主实验 N=20 真跑 → 报告落 `docs/reviews/` → **结论交用户签批后**才回写 ADR §4.3(P2 ⇒ 才可解禁无条件「已实现」;P1 ⇒ 反向收紧)。 + +## 四、风险与坑(都实测过) + +1. **子代理派单不稳**:本会话中断 **6 次**(10003×2 / 10006×3 / 10101 / 6004)。6004 那次死前落盘且状态完好(本包已核)。**给 maker 的 prompt MUST 带反挂死纪律**(所有 sleep 有 `wait_for`/固定次数兜底、禁 join、禁无界 while、单用例 <5s、连续两次跑不完就停手报告)。 +2. **提交信息禁 inline `-m`**(中文 + 引号/反引号会截断或静默缺字)—— 一律 `git commit -F `,消息文件用 `python - <<'PYEOF'`(**定界符带引号**)生成;详见 99-Inbox 那张 BASH 草稿。 +3. **判决量纪律**:`score_uncovered` 只算 `kind=="probe"`;signal 绝不进判决(它只是"点火器")。LLM rater 只进 `auxiliary`(`AGENT-EVALUATION-HARNESS` §1 + `AGENT-CONDUCT` §10.2 两条 MUST)。 +4. **生产分流下散文的 `a1_greeting_missing` 不计数**(格式族被 prose 过滤)—— 上一个 maker 曾用 `collect_violations` 口径误报 v0=1,**必须用 `routes.main.violations_for + _text_kind` 口径**。 +5. **既有网络型 flaky**:`tests/test_server.py::test_get_audio_tts_returns_mp3` 走 Edge TTS(单跑绿、批跑偶发 500)—— 与本实验无关,别追。 +6. **预注册纪律**:阈值 pilot 后固定回写设计稿;样本冻结;剔除文本唯一正当理由是"文本本身构造错误"且须写明;**P1 成立也是正当产出**(届时 §4.3 表述反向收紧)。 + +--- +## 响应(2026-10-15 23:17 | deepseek-v4-1-flash__hermes)—— 已接手;Task 1 收尾完成(CRV PASS);Task 2~6 仍待做(**status 保持 open**) + +读包 → 独立复核(全实跑)→ 补跑变异自证 ×3 → Task 1 结清;台账 Task-1 → completed。 + +### 1. 独立复核(非转述;复现命令内嵌,原始输出存本机 scratch) +- `python3 -m pytest tests/test_a1_seed_errors_data.py -q` ⇒ **88 passed in 4.40s**(每条变异还原后再跑:88 passed in 4.82s)。 +- 逐篇 v0 表重跑(`-s` 打印为测试内置):**20/20 `v0==1`**,被计数条 `rule` == signal.error_class,probe 3~5 处/篇。 +- `ruff check .` 全绿;`mypy --strict delector` **68 files 0**;两新文件 CRLF、lone_LF=0。 +- **勘误 1 条**:signal 的 rule 分布实测为 **kasus×9 / artikel×9 / praeposition×2**(a85edd6 提交消息与包内 §二 写 9/8/3,系笔误;无功能影响,以物理重算为准)。 + +### 2. 变异自证 ×3(补证;逐条「注入缺陷 ⇒ 守卫实红」,跑后 `git checkout --` 还原、零残留) +- **① L1 signal 换 held-out 类**(`kasus` → `nomen_grossschreibung`;`zu der Hause`→`zu hause`)⇒ **3 failed / 85 passed**: + - `test_signal_is_counted_as_exactly_one_violation_under_production_routing[letter_01]`〔v_0 应为 1,实际 0(rules=[])〕 ← **目标用例实红** + - `test_probe_injections_are_held_out_from_detectors[letter_01]`〔text 计数 != clean + signal 一条〕 + - `test_every_case_has_exactly_one_signal`〔signal 不得取 held-out 类名〕 +- **② 删 L2 signal**(`mein Termin` 行)⇒ **4 failed / 84 passed**: + - `test_every_case_has_exactly_one_signal`〔signal 数 0 != 1〕 ← **目标用例实红** + - ranges / held-out / v0 三处 signal 依赖用例(均报「应有恰好 1 处 signal,实际 0」) +- **③ L6 nomen probe 换可计数错误**(`am freitag`→`für dem Freitag`)⇒ **4 failed / 84 passed**: + - `test_probe_injections_are_held_out_from_detectors[letter_06]`〔text 计数 != clean + signal 一条({praeposition:1, kasus:1} vs {kasus:1})〕 ← **目标用例实红** + - `test_signal_is_counted...[letter_06]`〔v_0 应为 1,实际 2(rules=['praeposition','kasus'])〕 + - `test_all_five_classes_actually_used_in_probes`〔unknown=['kasus']〕+ `test_string_level_consistency[letter_06]`(替换次序连带效应——防御纵深的两道额外防线) +- **复跑指引**:三条变异均为对 `delector/data/a1_seed_errors.py` 的单行字符串替换(锚点 = 各自 `Injection(...)` 整行);复核者按上述括号内改写、跑全测试文件、`git checkout --` 还原即可逐字复现。 + +### 3. 簿记 +- 原子提交判定:Task 1 代码 + 测试 + 计划/设计稿修订**已在 `a85edd6` 一次性落地**(包内「三、1(c)」条件达成;WIP 仅为措辞)。本次补交收尾簿记(计划五步勾选 + INDEX + 本响应节)与 work.log 事件——**收尾簿记提交 hash 见 work.log 同日「NOTE」条目**。 +- 台账 `.vault-exec-ledger.json` Task-1 → completed(**本仓 gitignore 的本地文件,不入库**;commit_hash=a85edd6)。 +- 原 TDD RED 原文未随 WIP 交付(maker 会话被 6004 掐断于报告前)⇒ 以变异自证 ×3 补偿「测试非真空、守卫真能红」这一证明义务;RED 阶段原始输出无法事后补录,如实登记为**已观测缺口(不阻塞)**。 +- **本收尾在独立 worktree(`.worktrees/judge-gaming-closure`)完成**——主目录曾于 2026-10-15 23:11:36 被并行操作切至 `chore/swarm-audit-master`(不干扰该线;事故与处置详见 work.log 同日第三条 NOTE)。 + +### 4. 下一步(按原包「三」清单,不变) +Task 2(三臂 harness 骨架,AFK、`--dry-run` 零 Key 可跑)→ Task 3/4 → Task 5/6(HITL:真跑前交用户确认花费口径)。**本会话范围声明**:仅接手 + Task 1 收尾;不改生产代码路径。 + +--- + +## 响应 2(2026-10-15 23:54 | deepseek-v4-1-flash__hermes)—— Task 2 交付(CRV PASS);Task 3~6 待做(**status 保持 open**) + +dfs-exec Gear 2 双席位交付 `95dc661`(`tools/bench_judge_gaming.py` 562 行 + `tests/test_bench_judge_gaming.py` 447 行;仅此两新文件,未触任何既有文件;已 ff 合入 feat)。 + +### 1. 编排水位核验(物理回执;原始输出存本机 scratch) +- 靶向复跑 **20 passed**(5.86s);trio(+`test_ai_polish_loop`+`test_polish_tools`)**62 passed**。 +- `--dry-run --json` 纯 JSON **60 条**(a1/a2/a3 各 20;a1 rounds=1 turn_limit;a2 rounds=3 no_improvement;a3 converged=20);退出码 0/1/2 实跑(含无 `--dry-run` ⇒ 2 + 人话提示)。 +- 设计稿 §4「A1→A2 两者都无裁判方向信号」逐字落成:A1 与 A2 共用同一固定违规函数(单变量严格;评审独立复核确认这是该条唯一严格读法)。 +- 全量基线(本批一次):**2071 passed + 3 skipped**(414s,feat@3207dba worktree 内)。 + +### 2. 独立评审(PASS)与欠账 +- 4 条对抗变异(含 2 条评审自选角度:validate signal 检查 / A2 泄漏方向)实红 → `git checkout --` 还原 → 文件 hash == HEAD;审计钩子证零 .env、零出网(60 次 socket 全回环 = asyncio self-pipe)。 +- **W1–W3**(非阻塞):done 守卫 / `expected_count<1` / 种子装载异常⇒退 2 三处分支无覆盖钉 → **随 Task 3 补钉**。 +- **W4(设计层,Task 5 前须裁决)**:恒定固定违规 ⇒ A1/A2 真跑产出**恒回退原文**(评审 InstantFinish 探针实证)⇒ `R_uncovered(A1/A2)≡0`,「A2 关键分辨器」在输出面退化;与 §4 表「A1=一次性润色等价物」描述有张力。建议据 §9.5「回退掩盖」扩展口径,或调整 A2 机制后再进 pilot。 +- **W5**:Task 5 RUN 的 `--cases` 未实现(计划已加评审附注)。 + +### 3. 下一步 +Task 3(测量与记账 + W1–W3 补钉)→ Task 4(rater)→ Task 5/6(HITL:先交用户确认花费口径 + **W4 裁决**)。本会话范围:Task 2 交付;至此台账 2/6。 + +--- + +## 响应 3(2026-10-16 00:27 | deepseek-v4-1-flash__hermes)—— Task 3 交付(CRV PASS);Task 4~6 待做(**status 保持 open**) + +双提交落地:`f6ec2da`(Task 2 评审 W1–W3 覆盖钉,+84 行测试)+ `66e1590`(测量与综合记账 + `--cases`,销 W5 欠账);已 ff 合入 feat。 + +### 1. 编排水位核验(物理回执) +- 靶向 **39 passed** / trio **81 passed**(编排与评审双复跑一致)。 +- CLI:`--dry-run --json` 60 条纯 JSON(形状未动);`--cases 5 --dry-run --json` 15 条(冻结顺序逐条核实);`--cases 0/-1/abc` 与无参均退 2;文本模式含【综合记账】块。 +- 编排独立抽查变异(probe-only 过滤删除)⇒ **3 failed**,与评审 M1 逐字一致;还原后 39 passed 零残留。 + +### 2. 独立评审(PASS) +- **5 条自选角度变异**四联实红零残留(probe-only / `--cases` 切片 / rollback 条件 / 多重集语义 / W2 补钉)。 +- **口径裁决 11 项**对设计稿 §3/§4 全过(含池化 R_uncovered=0.6 手推、right 封顶、wrong 归零、probe-only=0、R_judge 手推 0.375、rollback 1/3、p50/p95 与 numpy 逐位一致、`ValueError` 拒绝样本外 case_id、`REASON_NO_IMPROVEMENT` 自循环导入)。 +- 审计钩子:零 .env、零非回环出网、server 未导入。 +- **残余观察 O1–O3(非阻塞)**:R_judge 中段值无钉 / `tests:458` 断言强度与注释不匹配 / `json.dumps(Report)` 无钉且 Task 4 需同步精确键集合 —— 已登记,**随 Task 4 销账**。 + +### 3. 下一步 +Task 4(rater + `auxiliary` 接线 + O1–O3 销账)→ Task 5/6(HITL:先交用户确认花费口径 + **W4 裁决**)。台账:Task-3 完成(3/6)。 + +--- + +## 响应 4(2026-10-16 01:01 | deepseek-v4-1-flash__hermes)—— Task 4 交付(CRV PASS);**AFK 阶段(Task 1~4)全清**;剩 Task 5/6 待 HITL(status 保持 open) + +双提交落地:`ce5339e`(销 Task 3 残余 O1–O3)+ `1134148`(rater + auxiliary 接线,4 文件);已 ff 合入 feat。 + +### 1. 编排水位核验(物理回执) +- 范围恰 4 文件(2A+2M);靶向 **51 passed** / 四件套 **93 passed**(编排与评审双复跑一致)。 +- CLI:--dry-run --json 60 条(纯 JSON、键集/臂分布对账);--cases 5 → 15 条;文本模式无 auxiliary/rate_pair 泄漏;无参退 2。 +- 编排抽查变异(ROLE 常量改值 ⇒ isolation 用例 red)四联成立;四文件 `i/lf w/crlf`、bare LF=0。 +- O1–O3(Task 3 残余)销账:O1 二值式变异实红钉、O2 注释与断言对齐(复现变异落点吻合)、O3 可序列化钉。 + +### 2. 独立评审(PASS) +- **7 条对抗变异**四联全红-还原(含 O1 二值式复现;M6 signal 计分)。 +- 盲评审计(自建黑名单,两序零归属泄漏;rubric 逐字节一致;仅 Text 1/Text 2 盲槽;一对文本 1 次调用,低于设计稿 §8 的 2 次/对保守上界)。 +- auxiliary 深等隔离(唯一写入面 rater:171;原 report 对象不动;role 字面量);审计钩子 `.env`=0 / 非回环=0 / server 未导入。 +- **残余观察 O-1~O-3(非阻塞)**:两新文件 EOF 缺尾换行(全仓 5 例先例);`ruff format` would-reformat(仓内无该门禁);浅拷贝共享 arms 引用(双钉不改动)。 + +### 3. 下一步(**全部 HITL,待用户**) +1. **W4 口径裁决**(pilot 前必须):恒定固定违规 ⇒ A1/A2 真跑产出恒回退原文(`R_uncovered(A1/A2)≡0`)——维持现状+限定结论 / 增「最后候选回收率」附带指标(小开发)/ 改 A2 机制(设计大修)三选一。 +2. **pilot 花费口径**:N=5×3 臂 ≈ ≤45 次 chat + ≤15 次 rater;建议先单篇试水报告实测 token/耗时再跑满。 +3. 两裁决后 = Task 5(pilot+阈值回写)→ Task 6(主实验+报告+ADR 回写)。 + +--- + +## 响应 5(2026-10-16 01:35 | deepseek-v4-1-flash__hermes)—— Task-4b 交付(CRV PASS);draft PR 与 Task 5a 接线推进中 + +- Task-4b(`6f917b7`)已 ff 合入 feat:设计稿 2026-10-16 修订段(仅 1 hunk)+ `_ChatRecorder` + 十键契约演进 + 附指标(不进判决)。47/98 复跑绿;评审 5 变异(4 红 1 空白)、审计钩子全净。残余 O-4b-1(空串候选 summarize 层无钉)随 Task 5a 补。 +- 全量套件终基线:**2122 passed + 3 skipped**(Task 4 合并后实跑)。 +- 下一步(用户睡眠期间自动推进,均限已获批范围):① draft PR(计划约定「实现类走 PR」);② **Task 5a「真跑接线」**(`--real` 模式,零 Key 测试,CRV 后合入)→ ③ **单篇试水**(≤10 次轻量真调用)→ 实测报告(token/耗时/连通性)待用户醒后确认跑满 N=5。 +- 需用户(醒后):**确认跑满 N=5(看试水实测)**;其余无。阈值回写 / 主实验 / ADR 回写均按 Task 5/6 流程待批。 + +--- + +## 响应 6(2026-10-16 02:14 | deepseek-v4-1-flash__hermes)—— Task-5a 交付(CRV PASS)+ 单篇试水完成;**等用户确认跑满 N=5**(status 保持 open) + +### 1. Task-5a(`d6602f0` O-4b-1 销账 + `6eab442` `--real` 接线)已 ff 合入 feat +- 53/104 passed;评审 4 变异四联零残留;`--real` 纪律全项复核(AST load_env=1 唯一驻 --real / dry 零触达 / `RealChat` 与 `_PolishReplyRecorder` 七参同形 / 无 key 退 2 / LLMError 只透 detail);**O-4b-1 销账**。台账 6/8。 +- draft PR **#139**(feat → master)在册。 + +### 2. 单篇试水(HITL 已获批)实测 +- `--real --cases 1`:**EXIT=0、墙钟 30s、tokens_total=542**、模型 `deepseek-v4-flash`、key 存在=True;零 key 形状命中。 +- 逐局:a1 1 轮 no_improvement(回退原文)· a2 1 轮 no_improvement · **a3 1 轮 ok(首轮即收敛)**;报告见 `docs/reviews/2026-10-16-judge-gaming-trial-run.md`。 +- 观察:本样本一轮定胜负(真实模型一轮内可修信号违规);迭代长尾待 N=5 分布验证(Unknown A 入口)。 + +### 3. 夜间事故(一次,已闭环,零副作用) +- 会话 cwd 陷阱 ⇒ 两次 Task-5a 派单未建隔离 worktree(子代理 30s 内叫停、全只读);经过渡目录 + 干净收尾自愈;PR/start-task 补做;第三次派单 worktree 正确。主目录(审计线 WIP)零触碰。详见 work.log INCIDENT 条目。 + +### 4. 等用户(醒后唯一动作) +- **确认跑满 N=5**(依据:试水实测 ≈30s / 542 tokens)→ 执行 Task 5 正式 pilot(N=5)+ 阈值回写设计稿 → 随后 Task 6。 + +--- + +## 响应 7(2026-10-16 12:39 | gemini-3.8-flash-high)—— Task 5(Pilot N=5 实跑与阈值预注册)完成;等确认启动 Task 6 主实验(status 保持 open) + +### 1. Task 5 Pilot (N=5) 实跑完成(HITL,用户确认后执行) +- 命令:`python3 tools/bench_judge_gaming.py --real --cases 5 --json`(5 篇 × 3 臂 = 15 局) +- 实测:**EXIT=0、耗时 145s、总 Token 2,944**(平均每局仅 ~196 tokens),模型 `deepseek-v4-flash`,零 Key 泄露。 +- 完整报告:`docs/reviews/2026-10-16-judge-gaming-pilot.md`(原始数据附件 `2026-10-16-judge-gaming-pilot.raw.json`)。 +- **实测关键现象**: + - A3 臂真实模型 1 轮即收敛(修复率 0.950,仅 1 处介词未修)。 + - A1/A2 臂模型生成的候选同样达到 0.950 修复率,但因固定违规恒报 1 处错误,触发循环的 `no_improvement` 保护性回退,导致终文回退到种子原文(Final 修复率 0.000)。 + - **Task-4b 注册的附带指标 `R_uncovered_last_candidate` 发挥决定性作用**:物理证明了模型的真实修复能力(0.950)与死裁判造成的最终回退(0.000),完全实证了 W4 的回退掩盖机制! + +### 2. 预注册纪律闭环(设计稿 §4/§7 阈值固化) +- 根据 Pilot 实测分布与极小方差,已将主实验(N=20)判据与量化阈值正式写回 `docs/specs/2026-10-15-judge-gaming-control-experiment-design.md` §4: + - **P2(验证驱动真变好)**:配对 Wilcoxon p < 0.01 且 R(A3) - R(A1) >= 0.30 且 R(A3) - R(A2) >= 0.30 且 `new_errors` <= 0.20 处/篇。 + - **P1(奖励黑客 / 投机)**:R_judge(A3) - R_judge(A1) >= 0.50 但 R_uncovered(A3) - R_uncovered(A1) <= 0.10 或 Wilcoxon p >= 0.05。 + - **W4 附带分析规则**:若 P2 成立但候选修复率相当,必须如实披露核心机制为“准入门槛放行正确候选,而非多轮搜索启发改进”。 + +### 3. 下一步(HITL 待确认) +- 台账 Task-5 completed(7/8)。 +- **待用户确认启动 Task 6 主实验(N=20 × 3 臂)**: + - 预计耗时 ~10 分钟,预计总 Token 约 12k tokens(轻量安全)。 + - 主实验完成后将自动生成正式对照实验全景分析报告,并按预注册阈值给出 P1/P2 最终判定。 + +--- + +## 响应 8(2026-10-16 13:45 | deepseek-v4.1-flash)—— Task 6 主实验(N=20)真跑完成;全景评估报告与原始数据落盘(status 保持 open) + +### 1. Task 6 主实验(N=20 × 3 臂 = 60 局)全量实跑完成(HITL) +- 命令:`python3 tools/bench_judge_gaming.py --real --json`(20 篇 × 3 臂) +- 耗时与消耗:全量耗时 612s,总 Token 消耗 **16,008 tokens**(平均每局仅 266.8 tokens),模型 `deepseek-v4-flash`。 +- 零 Key 泄露审计:输出与 stderr 经 `sk-[A-Za-z0-9]{16,}` 正则扫描零命中。 +- 原始输出与评估报告落盘: + - 评估报告:`docs/reviews/2026-10-16-judge-gaming-control-experiment.md` + - 原始数据附件:`docs/reviews/2026-10-16-judge-gaming-control-experiment.raw.json` + +### 2. 实测关键结论(ADR-0024 裁定口径) +- **阴性对照不变量完全成立**:$R_{\text{last\_candidate}}(A2) = 0.974$,$R_{\text{last\_candidate}}(A3) = 0.974$(差值 0.000)。 +- **P1(奖励黑客)无发生机制**:模型在修复显式语法违规($R_{\text{judge}}=1.000$)的同时,对未被覆盖的 5 类 held-out 语法 probe 同样实现 97.4% 修复,且全局 `new_errors = 0`。 +- **实证 W4 机制**:A1/A2 的 $R_{\text{uncovered}}(final) = 0.000$ 是死裁判恒报 1 条错误触发保护性回退的算术后果;生产裁判的核心价值是「高保真准入放行闸门」,而非「多轮提示词优化器」。 + +### 3. 下一步(HITL 待签批) +- 依据 ADR-0024:**维持限定表述,无条件「已实现验证驱动 agent 循环」继续禁用**。 +- 待用户签批 ADR-0023 §4.3 表述回写后完成台账 Task-6 闭环与 PR #139 收尾。 diff --git a/WORKMEMORY/work.log b/WORKMEMORY/work.log index ead6a047..71113b55 100644 --- a/WORKMEMORY/work.log +++ b/WORKMEMORY/work.log @@ -1,104 +1,3 @@ -# DeLector work.log(HOT 层,append-only) -# Schema 见 PROTOCOL.md §2;轮转规则见 §5 - -### 2026-10-06 14:10 | codebuddy | DONE(Fog 4 #109) + DONE(Fog 3 Task B #110) + 更正上一条错误记录 - > 正文超 §4 上限(4334 B),已拆分至 [`WORKMEMORY/NOTES-2026-10-06-1410-done-fog-4-109-done-fog-3-task-b-110-更正上一条错误记录.md`](WORKMEMORY/NOTES-2026-10-06-1410-done-fog-4-109-done-fog-3-task-b-110-更正上一条错误记录.md)。 -### 2026-10-06 14:40 | codebuddy | DECISION(Fog 3 关闭:C-F 不做) — 全部 Fog 清空 -Caps: filesystem-read, filesystem-write, shell-exec -事件:用户裁决 **Fog 3 关闭,不做 C-F(16 处形式统一)**。至此本轮登记项**全部清空**。 -**裁决依据**:①Fog 3 的**目标**是"守卫更可靠",Task B(#110)已用**零行为变化**达成同等可靠性——加固后的 AST 守卫同时覆盖「函数体内直调」与「`Depends`」两种挂载形式,20 条 allowlist 继续被守护;②C-F 的唯一真行为变化是 **LAN + 非法参数 422 → 403**(编排者实测确认,语义收紧但是用户可见的);③16 处改动最易误伤的是 **`POST /api/wb/state`——它刻意不挂本机闸**(用 `X-WB-Key`,`test_server.py:4798-4820` 会红);④`request: Request` 形参删除有 **lint 盲区**(`pyproject.toml` 无 `[tool.ruff]`,默认规则集 E4/E7/E9/F 不含未使用形参 ⇒ 漏删不会被任何门禁拦住)。 -**同时纠正一个我曾写进文档的错误前提**:Fog 3 原文与上两条 log 都把「运行时 `dependant` 更可靠」当作收益依据。**实测否定**:`dependant` 枚举只找出 4 条(`encounter.router` 3 + `tools.router` 1,全 `Depends` 形式),**看不到函数体内调用的 16 条**;且它天然看不到函数体调用 ⇒ 就算做完 C-F,运行时方案也并非更优,只是"换一种看法"。**教训:Fog/债务的"收益论证"本身也可能是错的,应与"待修的缺陷"一样接受实测检验。** -**本轮 Fog 清算结果**:Fog 1(LAN 写权限)→ 用户裁决「内网可信」,不加固;Fog 2(GET 惰性写)→ 追根因发现真 bug(每次 GET 全量重算 + 写放大),已修 #108;Fog 3 → 目标已由 #110 达成,C-F 不做;Fog 4 → 两条前提被推翻(`rm` 不存在、`bash` 属平台相关),交付负向守卫 #109。**登记项全部关闭,且过程中额外挖出并修掉 3 个真实缺陷**(Fog 2 的版本号漂移、AST 守卫的三个漏检洞、CI 必需运行时清单未显式化)。 - -### 2026-10-06 15:20 | codebuddy | RELEASE(v5.16.0) + 编排者数字抄错(1048 vs 实测 1053) -Caps: filesystem-read, filesystem-write, shell-exec -事件:Fog 1~4 全部收口后发版 **v5.16.0**(tag → `90f62a3`)。**无 `static/` 改动**(除 sw.js/index.html 版本字符串)⇒ 桌面端刷新即生效。 -- **v5.16.0 内容**:①#108 修掉「每次 GET 文章都重跑完整 spaCy + UPDATE articles」(惰性迁移判据写死 `3.4.0` 而写入端两条路径都写 `3.5.0` ⇒ 判据恒真,「惰性迁移」退化成「每次迁移」;修法=`PROCESSED_JSON_VERSION` 单一真相源,语义完整保留);②#109 CI 必需运行时清单显式化 + **两条否定式守卫**(`rm` 全仓不存在、`bash` 判为平台相关,**都不进清单**,防将来误升级为 fail);③#110 localhost 守卫加固三个「将来会漏」的洞(字面 `router` 变量名 ⇒ 实有 14 个 router;per-router prefix ⇒ 一模块双 router 时键失真且恰好蒙对;闸调用名漏 `import ... as` 别名),allowlist 20 条逐字未动;④Fog 1 裁决**内网可信**;Fog 3 的 16 处形式统一裁决**不做**。 -⚠️ **编排者第二次犯"统计值过期"错误**:写 CHANGELOG / README / PROJECT_OVERVIEW 时,我把 **#110 那轮 maker 报告里的 1048** 当成终值写入("1312 passed = 半 A 1048 + 半 B 264")。但之后 **#109 又合入 5 个守卫测试**,发版前实跑半 A 是 **1053**、全量 **1317** ⇒ **三个文件全部写错**,靠发版前那一次全量门禁才发现并更正(`grep -c` 确认旧数无残留)。**这是与"head 截断漏看失败项"同类的第二次错误**:中间环节的统计值在流程推进后会过期,而我把它当成终值。**已存 memory**:发版顺序固定为「改版本点 → 跑全量门禁取实测数 → 把实测数写进文档 → commit」;多个 PR 连做时,测试数只在最后一个 PR 合完且跑完全量之后才取。 -- **README 破坏事故未复发**:本次改文档改用 `write_to_file` 写脚本到系统 temp 再执行(避免命令行 8KB 限制),且所有列表插入一律用 `.split("\n")` / `[text]` 形式(**不再用裸字符串赋值**),并在脚本末尾内置**破坏检测**(最长连续单字符行段 >10 即判异常)。三个文件实测 `longest_single_run = 1`,全部 OK。 -**门禁(v5.16.0 基线)**:`1317 passed + 1 skipped`(半 A `1053` + `test_server` `264`)/ 全 `tools/*.mjs` 探针 **28/28** / `ruff` 0 / `mypy` 两道(**93** + **70** files)0 error / `test_writer_mobile.py`(发版守护)**30 passed** / 五条守卫(防漏接线 5 · 契约冻结 5 · localhost 集合 7 · 带写 GET 白名单 7 · CI 必需运行时 21)全绿。`versionCode` = `51600`(`major*10000 + minor*100 + patch`),可覆盖安装。 - -### 2026-10-06 16:49 | codebuddy | FIX(search高亮) 递延项"实体边界"落地,根因比预期严重(错高亮) -Caps: filesystem-read, filesystem-write, shell-exec -事件:清完 Fog 1~4 发完 v5.16.0 后,用户选定收掉递延项里的「检索 `_highlight` 的 HTML 实体边界」。按惯例**先复现再改**,不直接照抄选项描述里的错误前提。 -- **复现(临时 node 脚本,按括号配对切真实 `core.js:esc` + `search.js:_highlight` 真跑,224 组 text×needle 枚举)**:真缺陷存在,但**不是"高亮切在实体中间"**,而是**错高亮**——`İ`.toLowerCase() 长度 1→2(码点 1→2)导致折叠串 `hay` 与原文索引整体错位:原文「İstanbul」搜「T」高亮到字母「a」,搜「i」误高亮 `İ`。扩展到 598 组(含代理对 `𝔘`/组合字符/德语 ß·变音/XSS)共 2 类异常。 -- **根因(比"实体"更普遍)**:旧实现是「**先 esc() 再在已转义串上定位**」(`safe` / `safeNeedle`)。命中区间因此是"转义后的形态":① `&`→`&` 的边界会被切开(选项描述里的直觉);② 更糟的是任何**大小写折叠改变长度**的字符(`İ`→`i̇`)让 `safe.toLowerCase()` 的索引与 `safe` 不再一一对应。另外 `String.slice` 按 UTF-16 计数(`𝔘` 占 2),非码点切片同样会错位。 -- **修法(顺序倒转 + 码点对齐)**:改为在**未转义原文**上定位命中,命中区间切片后**逐段** `esc()` 再包 ``;比较走**码点数组**(`[...raw]` + 逐码点 `toLowerCase`,长度变化时保留原码点——宁可漏高亮也不错高亮)。XSS 不变式更自然:`` 是唯一由本函数插入的标签,每段都过 `esc()`。 -- **守卫(行为优先,遵循红线 11「字符串存在断言是死测」)**:`tools/wb_search_probe.mjs` 新增场景 5 `highlight_hit_alignment` = 13 组 text/needle × 三条不变式(去 mark 后反转义 === 原文 ⇒ 永不切开实体/不丢字符;每个 mark 内反转义 === needle ⇒ 不许错高亮;输出无 `