Repository navigation
feat(experiment): §4.3 第 8 条对照实验全量落地(Task 1~6 完工) - #139
Merged
Merged
Conversation
…,交接包已写) - 种子集:delector/data/a1_seed_errors.py + tests/test_a1_seed_errors_data.py(88 passed;20 篇 = 10 官方书信 + 10 非书信课文;每篇 1 signal + 3~5 probe;三层断言 + 信号层断言)。 - 编排者逐篇实测:20/20 生产分流 v0=1(signal rule 分布 kasus×9 / artikel×8 / praeposition×3);ruff / mypy --strict(68 files) 绿。 - 计划与设计稿回写:种子 = 每篇 1 信号 + >=3 held-out 探针(实测 v0==0 时实验不可识别);机制事实(polish_loop 不回灌裁判结论,模型只能主动调 writing_check 自查)与「反馈通道 = 下一子计划」入档。 - WIP 原因:maker 会话被 6004 掐断于报告前;缺变异自证 3 条与 CRV 验收 —— 清单在 WORKMEMORY/handoff_judge-gaming-experiment.md(本次交接包)。 - 附:HANDOFF 事件 + INDEX Active handoffs 挂载 + .probe-v0/.probe-signal 临时探针已清理。
- 变异自证(逐条实跑,跑后 git checkout 还原、零残留):① L1 signal 换 held-out 类 ⇒ 3 failed/85 passed(v0 用例「v_0 应为 1,实际 0」在列);② 删 L2 signal ⇒ 4 failed/84 passed(「signal 数 0 != 1」);③ L6 probe 换可计数错误 ⇒ 4 failed/84 passed(held-out 用例「text 计数 != clean + signal 一条」)。 - CRV PASS(接手方独立验收):88 passed 复跑;逐篇 v0 20/20==1;ruff 0;mypy --strict delector 68 files 0;两新文件 CRLF lone_LF=0。 - 勘误:signal 分布实为 kasus×9 / artikel×9 / praeposition×2(a85edd6 消息的 9/8/3 系笔误)。 - 交接响应节已追加(status 保持 open,Task 2~6 待做);INDEX 行同步。 - 附带:本收尾经独立 worktree 完成(主目录 23:11:36 被并行操作切至 chore/swarm-audit-master;为不干扰该线改用 .worktrees/judge-gaming-closure 隔离)。
…处置 NOTE - 三条事件:接手确认(复核基线 + 勘误 kasus×9/artikel×9/praeposition×2)/ 收尾记录(CRV PASS + 变异 ×3 实红 + 簿记提交 887282c)/ 事故处置(23:11:36 他方 checkout -b chore/swarm-audit-master;取证、还原、worktree 隔离续做)。
- tools/bench_judge_gaming.py(新增):
· Arm 三成员 A1_BASELINE / A2_NO_SIGNAL / A3_CURRENT;
build_arm -> ArmConfig(budget / violations_of 工厂 / arm_label);
run_arm -> RunRecord 九字段(arm / case_id / final_text / rounds / reason /
converged / tokens_used / elapsed_s / model)。
· CLI:--dry-run(确定性 stub chat 按轮次驱动全链路,零 Key 不出网)/ --json
(RunRecord 列表);退出码 0=完成 / 1=样本集无效 / 2=环境不可用(照
tools/bench_judge_fp.py 惯例);环境探测绝不自动下载模型。
- 三臂逐条照设计稿 §4:A1=Budget(max_turns=1);A2=Budget(max_turns=3)+恒定固定
违规(不读裁决体、不暴露任何被判违规内容);A3=Budget() 默认+生产分流。
A1 与 A2 共用同一个固定违规函数(设计稿 §3.2「两者都无裁判方向信号」的直接
推导)=> A1→A2 只变轮数、A2→A3 只变 violations_of(严格单变量)。
- 裁判/提示词/工具三臂共用:带 nlp 的生产同款 analyze_a1_email(内核默认裁判不带
nlp => 语法族恒不生效、v_0==0、实验对裁判信号不可识别)、pick_system_prompt、
POLISH_TOOL_ALLOWLIST;tokens_used/elapsed_s 取自循环自己的 done 事件。
- tests/test_bench_judge_gaming.py(新增):20 条契约测试(三臂配置与单变量等式、
A2 常量对全部 20 篇注入做泄漏检查、A3 与生产分流逐字一致、dry-run 行为级阶梯、
样本集校验与退出码 0/1/2、stdout 纯 JSON、零 Key tripwire、无 --dry-run 不触网)。
- 证据:RED=模块不存在(FileNotFoundError 收集失败)-> GREEN 20 passed(连同邻近
套件 62 passed);变异自证 ×2:A2 改生产分流 => 5 failed(含单变量用例)、A1
max_turns=3 => 4 failed(含阶梯用例),git checkout 还原后复绿、零残留;
ruff check . 全绿;mypy --strict(tools 档)+ --follow-imports=skip(tests 档)
全绿;两新文件 CRLF 零裸 LF;--dry-run --json 实跑 60 条记录(A1 1 轮
turn_limit、A2 3 轮 no_improvement、A3 3 轮 ok 且 20/20 收敛)。
- 计划 Task 2 五步勾选 + 收尾记录(含 W1–W5、全量基线 2071 passed + 3 skipped) - Task 5 评审附注:RUN 的 --cases 未实现;W4(A1/A2 恒回退原文)pilot 前须裁决 - INDEX 状态行 / 交接包「响应 2」/ work.log 事件(含独立评审证据与零 .env 零出网审计)
…装载异常退 2) 计划 Task 2 评审确认三处分支欠覆盖(删掉或改坏后原 20 用例仍全绿),本提交补钉: - W1:run_arm 的 done 事件守卫 —— 注入不发 done 的 async stub(拦 delector.services.polish_loop.run_polish_loop) ⇒ 断言 RuntimeError("拒绝伪造"),不许静默记 0 token; - W2:validate_seed_cases 的 expected_count < 1 分支 —— 构造 expected_count=0 破损用例 ⇒ 断言恰好报出该一条; - W2b:空 id / 重复 id 两分支 —— 空 id 用例 + 两篇结构不同、id 相同的用例 ⇒ 各断言恰好报出该一条; - W3:种子装载异常 ⇒ 退 2 —— monkeypatch load_seed_cases 抛 ImportError ⇒ main([--dry-run]) 返回 2,stderr 归口「环境不可用/种子集模块装载失败」。 每处均做单行变异自证(变异→红→git checkout 还原→复跑绿→git status 空),零残留。 只改 tests/test_bench_judge_gaming.py(+5 用例;20 → 25 passed)。
计划 Task 3 落成(严格 TDD:RED 原文 14 failed / 25 passed → 实现 → GREEN): - score_uncovered:判决量分子(只算 kind=="probe";right 回来且 wrong 不残留的逐处计数; right 按 expected_count 封顶;signal 永不进判决量); - score_judge_violations:R_judge 计数来源(生产同款裁判 + 生产分流 _polish_violations_of); - detect_new_errors:error 级多重集差(「修一坏一」= 1 —— 总数差口径会净记 0); - summarize:每臂 runs / R_judge / R_uncovered / rollback_rate / new_errors / tokens_total / elapsed_p50 / elapsed_p95 / rounds_mean;Report.judgement_basis="uncovered_seed_recovery" (测试钉住);记录引用样本集外 case_id ⇒ ValueError; - CLI:新增 --cases N(≥1;切片确定性;无效值 argparse 退 2);--json 输出形状不变 (RunRecord 列表,Task 2 契约);文本模式新增【综合记账】块(销 Task 5 的 --cases 欠账)。 收尾:39 passed(靶向)/ 81 passed(trio);--dry-run --json 纯 JSON 60 条不变; --cases 5 --dry-run --json 15 条;无参数退 2;ruff 全绿;mypy --strict delector tools 94 files 0 + mypy --follow-imports=skip tests 128 files 0;两文件 CRLF(薄 LF=0)。
…观察 O1–O3 登记 - 计划 Task 3 五步勾选 + 收尾记录(39/81 passed、5 变异四联、口径裁决 11 项) - Task 5 附注更新:--cases 已随 Task 3 落地销账 - INDEX / 交接包「响应 3」/ work.log 事件
…可序列化钉) - O1:新增 test_summarize_pins_r_judge_mid_values_not_binary —— 构造 v0=3、vfin 分别 1 与 2 ⇒ R_judge = 2/3 与 mean(2/3,1/3) = 0.5(两个非端点读数);二值式变异 (1.0 if vfin==0 else 0.0)实测红(0.0 ≠ 2/3)。 - O2:test_score_uncovered_counts_probe_recoveries_place_by_place 两条断言与注释逐条对齐: 「signal 不入分子」由 SIG_R 断言把关(单行变异 if False: continue 实测红:4 ≠ 3); 「残留一票否决」由 SIG_W 断言把关(残留检查提升出循环的结构化变异实测红:0 ≠ 3)。 只动 signal 处理的单行变异改不动 SIG_W 读数(探针过滤先于残留检查 ⇒ 该输入对这类缺陷 天然不可见),注释已如实改写、不再声称错误的敏感面。 - O3:新增 test_summarize_report_is_json_serializable —— json.dumps 往返无损断言;往 summarize 的 return 混入集合(非 JSON 原生对象)的变异实测红(TypeError: set is not JSON serializable)。 证据:三处四联(变异→红→git checkout 还原→复跑绿→status 空);靶向 41 passed; 被改文件 CRLF、bareLF=0、CRCRLF=0。
新增 tools/bench_judge_rater.py(纯 stdlib:无 Key 载入路径、无默认 chat、不 import 仓库模块):
- rate_pair(before, after, *, order_seed, chat) -> Rating:order_seed 确定性决定呈现顺序
("ba"/"ab" 两分支);两个顺序共用逐字一致的 rubric;两段文本以 Text 1/Text 2 中性盲槽
呈现,请求全文不含臂标签或「哪份是润色后/原文」暗示;一对文本一次调用(两段 × 两维四项分,
设计稿 §8 的「≈120 次」是 2 次/对上界);畸形回复 / 空文本 ⇒ ValueError(辅助信号宁缺勿假)。
- insert_into_report(report, ratings) -> Report:只写 report["auxiliary"] =
{role: "auxiliary_signal_not_used_in_verdict", ratings: [...]},返回新 dict、原 report 不动。
- 调用形制与 run_polish_loop 的 chat 调用同形(messages / model="" / timeout / max_tokens /
response_format);真 chat 接线留 Task 5/6。
tools/bench_judge_gaming.py:summarize 的 Report 新增 auxiliary 槽(恒 None = 未运行 rater),
判决字段零改动;--dry-run CLI、依赖预热链均结构性不触 rater(AST tripwire 钉住)。
tests/test_bench_judge_rater.py(新,9 条)+ tests/test_bench_judge_gaming.py(键集合断言
同步 + 新增 dry-run 用例):
- 盲评协议:顺序两分支、去盲映射(判别性 stub 按文本内容给分)、两序 rubric 逐字一致、
零归属泄漏(黑名单逐词扫描);
- auxiliary 隔离:写评级后 judgement_basis 与 arms 逐字未变、role 标记、整体可 JSON 序列化;
- dry-run 零网络三重闸(socket 非回环/DNS 闸 + llm_client.chat 炸雷 + 零调用断言)+
AST 层「不引用 rater 符号 / 预热链不含 llm_client」tripwire。
变异自证 ×2 实红:① 臂标签塞进 rubric ⇒ 归属泄漏用例红(定位到黑名单断言);
② rating 写进 judgement_basis ⇒ 两条隔离用例红。还原后逐字节一致(sha 复核)零残留。
门禁(全实跑):靶向 51 passed;四件套(+test_ai_polish_loop+test_polish_tools)93 passed
(另 test_judge_fp_bench 10 passed);--dry-run --json 60 条纯 JSON 无 auxiliary 泄漏;
--cases 5 ⇒ 15 条;无参退 2;ruff check . 全绿;mypy --strict delector tools 95 files 0;
mypy --follow-imports=skip tests 129 files 0;四文件 CRLF、bareLF=0、CRCRLF=0。
…K 全清 + 残余观察 O-1~O-3 登记 - 计划 Task 4 五步勾选 + 收尾记录(51/93 passed、7 变异四联、盲评审计、auxiliary 深等隔离) - INDEX / 交接包「响应 4」(AFK 阶段全清,剩 HITL 两裁决)/ work.log 事件 - O1–O3(Task 3 残余)已销账;O-1~O-3 新残余登记
- work.log DECISION 事件(选项 2 语义:R_uncovered_last_candidate + candidates_recorded,不进判决;试水两步走) - INDEX 状态行更新(Task 1~4 交付 → Task 4b 在途 → Task 5/6 HITL) - 台账插入 Task-4b(总任务 6→7,completed 保持 4)
…2+3 + O-4b-1 登记 - 计划新增 Task-4b 块(用户裁决登记 + 验收 + 残余 O-4b-1) - INDEX / 交接包「响应 5」(draft PR、Task 5a、试水路线图) - work.log:套件终基线事件 + Task-4b 交付事件
`last_candidate_text=""` 是**合法候选**(`_ChatRecorder` 口径「含该键即记录」,已有用例钉住): 把它纳入 `test_summarize_last_candidate_metrics_pool_only_candidate_records` —— `candidates_recorded` 含它、候选分母含其 probe 处数(pb 的 2 处),0/2 真实进池化分子分母。 数字更新(synthetic):candidates_recorded 2→3、R_uncovered_last_candidate 2/3→2/5、 R_uncovered(final 口径)1/4→1/6;两条分母口径对照随新记录同步重算 (按记录等权 0.5 ≠ 2/5;无候选也入分母 1/3 ≠ 2/5)。 四联自证:把 summarize 的 `if record.last_candidate_text is not None:` 改成真值判断 `if record.last_candidate_text:` ⇒ 本用例必红(实测 assert 2 == 3,1 failed)→ `git checkout` 还原 ⇒ 复跑绿(1 passed)→ status 仅本测试文件 M(工具文件零残留)。 零 Key、零真实网络:本用例纯字符串口径,无任何外部调用。
- CLI:新增 --real(真跑 HITL);与 --dry-run 互斥(同给 ⇒ argparse 退 2); 无模式旗标 ⇒ 退 2 且文案更新为「需 --dry-run 或 --real」;--cases 与 --real 同用照常(切片在装载后、校验前)。--json 仍为十键 RunRecord 列表(输出面不动)。 - 真跑链路(全在 tools/ 内,不动生产代码): 运行期经 delector.server.load_env() 载入环境(全文件唯一调用点、只住本分支; dry-run 侧有「调用即 fail」的 stub 钉住它不被触碰); 真 chat = RealChat,与 routes.main._PolishReplyRecorder(ai-polish 生产构造) 逐参同形(循环的空串 model 被忽略、以生效模型名出网;timeout/max_tokens/ response_format 原样透传 ⇒ 单次调用有界 = min(30.0s, 剩余 deadline);无重试), 仅增设 model_name / key_present 两个非泄值读取面; key/base_url 取值走 llm_client 判定面(getattr 取属性:绕开 llm_client 裸 re-export 与 mypy --strict no_implicit_reexport 的冲突,且保住该 monkeypatch 面); 真跑前 stderr 只打印 key 存在布尔与生效模型名(绝不打印 key 本体); 失败语义:无 Key / 依赖不可用 ⇒ 前置退 2;上游 LLMError ⇒ 显式退 2 + 人话原因、 不产出任何部分结果(退码 2 已钉进测试);文本模式头行如实标注真跑、不复读 「零 Key、不出网」。 - 测试(全 stub、零 Key、零真网;6 新 + 4 改):load_env 恰调用一次;llm_client.chat 以生产同形 kwargs 被调(含 key/base_url 的 rstrip 口径 / JSON_OBJECT / 有界 timeout); 生效模型名进 RunRecord.model(≠ DRY_RUN_MODEL);无 key ⇒ 退 2 且零 chat 调用; 上游异常 ⇒ 退 2 + stdout 全空(零部分结果)+ 只透 detail 不透 raw(raw 里的假 key 不外泄);假 key 输出/异常全程 tripwire;dry-run 全链路零网络不变量保持 (socket 闸 + chat 闸 + load_env 闸 + AST:仓库 import 全住函数体内); 源码 tripwire 演进为「load_env 调用点恰一处 + 不含 DEEPSEEK_API_KEY」。 (另补:4 个真跑用例在 main 前冲掉 import 期诊断行 —— 单独跑也成立,不依赖文件序。) - 变异自证 ×2 四联:① 真跑前打印 key 值(泄漏)⇒ 键闸用例红(假 key 出现在 stderr); ② --real 静默回退 dry 桩 ⇒ 4 个真跑用例红(load_env 0 次 / rc 0≠2 / 无真 chat / 无模型名)。 两者均:变异 → 复跑红 → 还原(sha256 复核)→ 复跑绿 → status 仅两文件 M。 - 门禁:pytest 53 passed;四件套 104 passed;ruff check . 全绿; mypy --strict(工具文件)+ mypy --follow-imports=skip(测试文件)双绿; 两文件 w/crlf、bare LF=0。零真实网络:全部测试走 monkeypatch stub(load_env / chat / key 面),真跑由 HITL 在合入后另行触发(本提交不含任何真实调用)。
- 计划新增 Task-5a 块(接线验收 + O-4b-1 销账 + 试水记录) - INDEX / 交接包「响应 6」(试水实测 + 事故回执 + 等确认 N=5) - work.log:INCIDENT(cwd 陷阱闭环)+ Task-5a 交付 + 单篇试水 三事件 - docs/reviews/2026-10-16-judge-gaming-trial-run.md(试水实测:EXIT=0 / 542 tokens / 30s)
- docs/reviews/2026-10-16-judge-gaming-trial-run.raw.json(逐局全文 + stderr + 退出码/墙钟) - 报告内「原始输出」行改指该附件(原写的仓库同级 scratch 未适用:repo scratch/ 未被 ignore)
- 运行 5 篇 × 3 臂实跑:EXIT=0、145s、2944 tokens,原始数据落盘 docs/reviews/2026-10-16-judge-gaming-pilot.raw.json - 产出 Pilot 报告 docs/reviews/2026-10-16-judge-gaming-pilot.md,实证 W4 回退掩盖机制 - 依据实测极小方差固化主实验判据阈值回写设计稿 §4(P1/P2/W4 规则) - 计划 Task 5 勾选完成 + INDEX / handoff 响应 7 / work.log 簿记同步
- 20 篇 × 3 臂 = 60 局真跑完成(EXIT=0,耗时 612s,Token 16,008) - 原始数据落盘 docs/reviews/2026-10-16-judge-gaming-control-experiment.raw.json - 依据 ADR-0024 裁定口径产出全景报告 docs/reviews/2026-10-16-judge-gaming-control-experiment.md - 实证阴性对照不变量(A2 ≡ A3 = 0.974)与 W4 回退掩盖机制,证伪 P1(无发生机制) - 设计稿 §11 执行记录补齐 + 计划 Task 6 步骤推进 + INDEX / handoff / work.log 同步
ROM4n2
marked this pull request as ready for review
October 16, 2026 05:33
…-only 冲突:双方事件按时间序全保留)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
目的与背景
ADR-0023 §4.3 判据第 8 条(「浅裁判 + 循环 = 奖励黑客」是否成立)的对照实验全量落地。
依据 ADR-0024(第 8 条对照实验判决量与结论边界)裁定的口径完成全景评估与闭环。
docs/specs/2026-10-15-judge-gaming-control-experiment-design.md(含 2026-10-16 Pilot 阈值固定与 §11 完工记录)docs/plans/2026-10-15-judge-gaming-experiment.md(8/8 全交付,台账 100% 闭环)docs/reviews/2026-10-16-judge-gaming-control-experiment.mddocs/reviews/2026-10-16-judge-gaming-control-experiment.raw.json(60 局真跑明细)核心物理发现与实验结论(ADR-0024 裁定口径)
new_errors = 0。rollback_rate = 1.000)的算术后果,并非模型未产出正确修复。交付与门禁验证
sk-…扫描零命中,零出网泄露。