Skip to content

Latest commit

 

History

History
859 lines (768 loc) · 64.9 KB

File metadata and controls

859 lines (768 loc) · 64.9 KB

DEBUG.md — 修复经验簿

dogfood 五轮(round-1~5)与补测会话真实修复之 bug 清单。每条记症状 → 根因 → 修复 → 可迁移经验。 新会话排障时先查此簿;修完新 bug 须回填。

总览

# 缺陷 轮次 版本
1 运行态文件混入变异提交(爆炸半径 3→42 虚胖) solidify round-1 v1.108.0
2 裸 venv python 下验证级联全跳过(unvalidated success) solidify round-1 v1.108.0
3 15 个存量 mypy 平台错误卡死所有 gated run 全仓 round-2 v1.109.0
4 测试直读宿主仓库真实状态(宿主相关失败) tests round-2 v1.109.0
5 降级周期白烧一整个进化 tick(首 tick 延迟) dispatch round-3 v1.110.0
6 蒸馏静默零产出(宿主无从自纠格式) swarm_distill round-4 v1.110.1
7 选择器反复重派已落地基因 selector round-5 v1.111.0
8 冷却死代码(flag 默认关致事件尾永不加载) selector round-5 v1.111.0
9 complete_agent 无视失败契约(ok: False 照常推进) workflow 补测 v1.112.0
10 技能基因哈希失配被静默丢弃 skill_assets v1.104 v1.104.0
11 solidify 回滚 stash 重放陷阱 运维 round-2 运维经验
12 MCP 宿主可自批 skip / 自恢复监督 hitl/hotl 审阅 v1.112.0
13 固化提交与冷却记剧本基因、不记落地基因 solidify/selector round-4 实证 v1.112.0
14 MCP 探针单通道解包致工具面全 FAIL(假阴性) 测试工具 MCP 接入 运维经验
15 探针断言口径三处错(假阴性第二批) 测试工具 MCP 接入 运维经验
16 venv 旧模块疑虑 + stdio 长驻进程不重载 部署 MCP 接入 运维经验
17 工具面缺两个:配置/服务端/客户端三层排查 部署 MCP 接入 运维经验
18 asset_search 多词必空 + summary/signals 不入检索 mcp_server 工具体检 未发版
19 重复固化烧级联 + 幻影成功事件污染 soak 样本 solidify round-12 未发版
20 谱系链测试假设同 run 双固化(与 #19 守卫冲突) tests round-12 未发版
21 paths.py 诊断打 stdout,CLI --json 契约全破 cli/paths round-13 未发版
22 级联在宿主残废 PATH 下验证 + 证据只存头 2000 字符 solidify round-13 未发版
23 DEBUG #20 真凶:legacy 回滚 cwd 缺失,级联中删真实运行态 solidify/cli round-13 未发版
24 preflight 负载阈 1.5 平坦常数,多核宿主永久被拦 guards round-14 未发版
25 验收门饥饿:PATH 盲区 + 全量 argv 单超时 → 永远 0 分、基线永不落盘 acceptance round-14 未发版
26 T0 门与级联种群错位(402 幻影失败)+ 未隔离管线测试污染真实运行态 acceptance/tests round-15 未发版
27 新增源码型资产只跑靶向检查就提交:ruff I001/E501 + mypy 同名模块连拒两次 assets/mypy round-16 未发版
28 stale 宿主惰性导入崩成裸 ImportError;工具目录暴露于回滚处置 swarm/gitignore round-17 未发版
29 meta-report transfer 维度两度过松:常驻信号头背景虚报「迁移」 ops/meta_report round-18 未发版
30 效率维度混合种群平均 + 失败事件验证成本零痕迹 meta_report/solidify round-19 未发版
31 时长测量用挂历时钟:系统睡眠 5.1h 计入 pytest 段(88 倍虚增) solidify round-20 未发版
32 验收门 layer_id 前缀翻倍(存档往返腐蚀);soak 判定 false_kill_high acceptance round-21 未发版
33 T0 分块超时不重试 + 重复间分歧直接进均值 → 伪杀;preflight 测试未隔离 user-lock acceptance/guards round-22 未发版
34 遥测仪器自外于锚/机制面;失败事件缺隔离元数据;探针夹具撞统计阈值边界 anchor/meta_report round-23 未发版
35 soak 判定全历史窗口:校准前伪杀永不过期,稀释路径 perverse acceptance/report round-24 未发版
36 裁决粒度盲区:固定大极差阈放行单测试噪声(1/3519)拖垮均值 acceptance/orchestrator round-25 未发版
37 测试泄生产 wiki(gene-1 噪声 128/161)+ set_flag 进程内无撤销泄漏 tests/conftest round-26 未发版
38 门校准语义无仓外冻结:验证者相邻不变量只受可同谋测试保护 anchor round-27 未发版
39 幻影 preflight-abort 快照:测试泄漏的信号被选择器当真 pipeline/signals round-28 未发版
40 shell 模板执行器:原始占位符值即注入面(Mimosa triage) gep/llm_template round-29 未发版
41 验收门终态死锁:ready 结构性不可达 + phase 指标读数饱和 acceptance/report round-30 未发版
42 T0 基线测量不对称:单浮点合成伪观测放行退化或误杀 acceptance/orchestrator round-31 未发版

条目

1. 运行态混入变异提交(round-1)

  • 症状solidify 报告爆炸半径 42 文件,变异本体只动了 3 个。
  • 根因_commit_mutation 把守护进程实时写的 memory/.evolver/evolver/.config/ 全部 stage——引擎自己的运行痕迹污染了自己的变异审计。
  • 修复_is_runtime_state(rel) 过滤,提交目标与爆炸半径计算共用同一过滤。
  • 经验自观测数据永远不得进入被观测对象的变更集。凡引擎「提交工作区」类 功能,先问:哪些文件是引擎自己在写的?

2. 裸 venv 下级联全跳过(round-1)

  • 症状:solidify successgated_runs 不增——三阶段全部 skip
  • 根因:PATH 无 ruff/mypy/pytest 时级联命令解析失败 → 静默跳过 → 无验证即通过。
  • 修复get_fitness_cascade_commands 回退 <sys.executable 目录>/工具; 子进程级测试清洗 PATH 复现真实场景。
  • 经验「跳过」与「通过」语义必须可区分且默认从紧——静默降级的安全机制 等于没有机制。unvalidated success 是验收门最危险的假绿。

3. 存量 mypy 平台债卡级联(round-2)

  • 症状:级联首次真实执行 mypy 即挂 15 个错误(winreg/windll/creationflags 等 Windows-only 属性)——此前从未暴露,因为级联从未真正跑过(见 #2)。
  • 修复:统一 getattr(module, name, default) 惯用法(运行时零变化); 删除 4 处已漂移的 unused-ignore。
  • 经验修复一个静默降级会暴露其下游积压的全部债务——预算上要预期连锁; 跨平台属性一律 getattr,不写平台条件 type: ignore(会在另一平台变 unused-ignore)。

4. 测试直读宿主状态(round-2)

  • 症状test_repair_loop_circuit_breaker_empty 在真仓里 consecutive == 2 失败。
  • 根因:未隔离 GEP_ASSETS_DIR,读到了宿主仓库真实的 repair+failed 事件。
  • 修复:补 monkeypatch.setenv 隔离(同 conftest.temp_workspace 模式)。
  • 经验凡读状态文件的测试必须显式隔离路径环境变量——dogfood/真仓运行 会让「本地绿」变「宿主红」。AGENTS.md 坑阱篇早有此训,仍被漏——排障时先查隔离。

5. 降级周期白烧 tick(round-3)

  • 症状:注入信号后需 2 个 tick 才 dispatch;首个 tick 报 idle_cycle
  • 根因dispatch_phase 把「跳过 Hub 调用」与「跳过本地 dispatch」混为一谈 ——Hub 降级标志被消耗的那个 tick,即便基因已选中也不出提示词。
  • 修复:按 hub_skip_reason 分裂语义:饱和稳态(无理由)保持 idle; autopoiesis_degraded / preflight_abort_recovery 仍本地 dispatch。
  • 经验一个布尔位承载两种语义时,先拆语义再修行为。实证方法: 设标志 + 单 tick 直击修复路径,对照修复前后 dispatch_reason

6. 蒸馏静默零产出(round-3/4)

  • 症状swarm_distill 返回 genes: 0errors: []——宿主不知格式错在哪。
  • 根因:纯文本响应无 ```json 块时零提取属正常路径,但无任何指引; 另有 Gene.category 枚举陷阱(`"innovation"` 非法,合法值 `repair|optimize|innovate|explore`)。
  • 修复:零资产时附 hint(期望块形状 + 合法枚举)+ next_action= resubmit_with_asset_blocks;坏块时 errors 与 hint 并列。
  • 经验人机接口的「空结果」必须携带「如何不空」;同族陷阱: EvaluationFeedback.metrics 只收 dict[str, float](字符串值直接 ValidationError)。

7. 选择器重派已落地基因(round-5)

  • 症状:round-3/4 的 tick 反复选中 round-1/2 已固化的基因(同信号仍在语料、 同基因仍最佳匹配),每次浪费一个完整周期。
  • 修复:近窗成功固化基因 ×0.25 惩罚(非禁选:唯一匹配仍可选); EVOLVER_APPLIED_GENE_COOLDOWN_EVENTS / _PENALTY 可调。
  • 经验重复选中所以内聚地发生,是因为状态(已应用)没进决策输入—— 排障顺序:先确认决策函数看得见哪些状态,再调权重。

8. 冷却死代码(round-5,藏在 #7 之下)

  • 症状:惩罚实现后实证仍选旧基因——两段式根因。
  • 根因:事件尾取自 ctx["recentEvents"],而该键由 enable_event_history (默认 False)控制加载——flag 关时冷却永不触发;且窗口被 x1 类簿记噪音 事件稀释(先过滤有效事件再取窗修复)。
  • 修复:冷却自取事件尾(与 flag 解耦);窗口只计带 outcome 的 mutation 事件。
  • 经验依赖注入键若由别的 flag 决定存在性,新消费者必须自取或显式断言。 三段实证(噪音稀释 → flag 根因 → 决定性通过)是此类「改了但没生效」的标准解法。

9. complete_agent 失败契约失效(补测会话)

  • 症状:新测试断言失败任务应使 run 失败,实际却推进到 waiting_approval
  • 根因complete_agent 不看结果内容——CLI --fail 与 swarm complete 的 失败语义形同虚设。
  • 修复:dict 结果携带 ok: False 即失败该 run(WAL 记 agent_failed), 与 approval/gate 失败语义对齐。
  • 经验外部报告的失败必须成为状态机转移。补测方式:覆盖审计 (pytest --cov)找冷分支 → 写「应然」测试 → 暴露「实然」缺口。

10. 技能基因哈希静默丢弃(v1.104)

  • 症状skills sync 后基因入库但加载时「消失」。
  • 根因:skill2gep 本地哈希公式(repr 基)≠ asset_store 规范化哈希; load_genes() 对哈希失配静默跳过(防篡改设计,但也吞掉了集成错误)。
  • 修复sync_skillscompute_asset_id 重算。
  • 经验内容寻址系统的写入方必须复用读取方的哈希函数;两处「各自正确」 的实现对接时,哈希是首个断言点。

11. solidify 回滚 stash 重放(运维,round-2)

  • 症状:solidify validation_failed 后变异消失;stash 列表有 "evolver rollback" 但 git stash pop 既保留条目又不还原文件。
  • 修复(操作法)git checkout 'stash@{N}' -- <files> 可靠重放;事后 drop 全部相关 stash(变异可能在 stash@{1} 而非 stash@{0}——memory 运行态与源码 混在相邻两个 stash 里)。
  • 经验引擎回滚产物的重放永远用 checkout,不用 pop

12. MCP 宿主自批 skip、自恢复监督(v1.112 审阅)

  • 症状:文档写 HITL/HOTL 是人类门;MCP 工具 swarm_approval_resolve / swarm_supervise(resume|unveto) 默认 by=human-via-host,无人值守宿主 可自己批准 skip_validation、自己解除暂停。
  • 根因:审批与监督被做成「宿主转达」而非带外通道;instrument 写「先问人」 只是提示词。EVOLVER_HITL_MODE=ON/disabled 也不等于 on(大小写/未知值 静默保持 off)。
  • 修复parse_hitl_mode(未知 fail-closed 为 on);AUTO_HIJACK=1 强制 HITL 且拒绝 MCP 转达的 approve/resume/unveto(改走 CLI);pause/veto 进入 _run_single_cycle;损坏的状态文件 fail-closed。
  • 经验「请先问人」不是门。凡高危动作,默认关闭的审批 + 同一 stdout 上的转达工具 = 宿主既是申请者也是批准者。无人值守必须切断转达或另开通道。

13. 提交说明与冷却罚错基因(round-4 实证,v1.112 修)

  • 症状:git 提交 d68a7fcgene_hub_fetch_resilience,实际改的是 distill 格式提示(蒸馏基因为 gene_distill_format_hint)。冷却窗口跟着 剧本 id 走,罚错对象。
  • 根因_commit_mutation 与冷却只读 selected_gene_id(dispatch 选出的 剧本)。宿主按剧本改树后 distill 出的新基因从未写回事件。
  • 修复swarm_distill 把落地 id 写入 solidify state;事件同时带 gene_idlanded_gene_id(s);提交说明优先落地基因;冷却对两类 id 都罚。
  • 经验决策输入、审计输出、冷却键必须是同一标识。历史 round-1~5 事件只有剧本 id——冷却对旧事件会天然失效一个窗口,属预期成本,不必回填。

14. MCP 探针单通道解包致工具面全 FAIL(MCP 接入,2026-09-05)

  • 症状:stdio 烟测 22 项里 8 项工具面检查全 FAIL(返回 None),协议面 (initialize/resources/prompts)却全过——疑服务端工具坏。
  • 根因:探针只读 structuredContent;该构建下服务端把 dict 结果序列化为 content[0].text JSON(pretty-printed)且不带 structuredContent 字段。 后经 ZCode 客户端实际连接发现两通道皆有——通道可用性随客户端能力协商 而异,探针写死了单一假设。
  • 修复:双通道解包——优先 structuredContent(含 {"result": ...} 解包), 退化为 json.loads(content[0].text)
  • 经验测试工具自身的 bug 会伪装成被测物的全面故障。协议面过、 数据面全挂这种「一刀切」的失败模式,先怀疑探针的解包/断言层,再怀疑服务。 另:裸 timeout 管道在 macOS 静默无输出(无 GNU coreutils),子进程超时 用 Python communicate(timeout=)

15. 探针断言口径三处错(MCP 接入,2026-09-05)

  • 症状:解包修复后仍 3 项 FAIL:approvals / supervise status / AUTO_HIJACK approve 阻断。
  • 根因:三处断言与实现口径不符——swarm_approvals 返回 {pending, recent}(非 requests/ok);swarm_supervise 的 state 嵌套于 supervision.stateswarm_approval_resolve 的参数是 approve: bool 而探针传了 decision:(approve 默认 False → 阻断分支自然不触发)。
  • 修复:按真实返回键形与参数名修正断言,22/22 全过。
  • 经验写断言前先抓一次原始响应(raw dump),别凭记忆写键名。 布尔参数传错名是静默的:默认值让调用「成功」却测不到目标分支。

16. venv 旧模块疑虑 + stdio 长驻进程不重载(MCP 接入,2026-09-05)

  • 症状:用户担心 MCP 配置用的是旧安装模块,问是否要重装、是否要 禁用再启用。
  • 核实.venv/lib/.../ _editable_impl_evolver.pth——uv sync 默认 可编辑安装,evolver.__file__ 直指 src/evolver/;服务端线上回报 1.112.0(含未提交工作树)。无需重装。
  • 经验Python stdio server 是长驻进程,代码在 spawn 时载入。 四条推论:(a) 工作区 MCP 配置在会话启动时加载——会话中途写入的配置 本会话不可见,需新会话;(b) 改完引擎源码后必须重连 MCP 才加载新版; (c) 中间快照现象——两次修复之间重连,进程会「半新半旧」(先修的 生效、后修的缺席);ps -eo pid,lstart,command | grep mcp_server 对比 提交时刻可一锤定音;(d) 设置页重连只换进程,已开会话的管道仍绑旧 进程——工具行为不变时须重启会话。验证模块新鲜度一行命令: python -c "import evolver; print(evolver.__file__, evolver.__version__)"

17. 工具面缺两个:三层排查法(MCP 接入,2026-09-05)

  • 症状:客户端模型工具面 21/23,缺 swarm_solidifyswarm_approvals (两者无共性:一 destructive、一 read-only、schema 正常)。
  • 排查:(1) 配置层——~/.zcode/cli/config.json 与工作区配置均规范、 无 enabled:false、无工具过滤字段;(2) 服务端层——直连 tools/list 23 个全注册、schema/注解齐全;(3) 客户端组装层——无法从外部观测, 但「destructive 注解被隐藏」假设被反例排除(三个 destructive 工具 可见)。结论:长会话(1000+ 消息)中途接入的服务器被客户端工具面 裁剪,裁谁近似随机。
  • 经验假阴性排查自底向上:证明每层干净再上移,反例优先于假设 (一个可见的 destructive 工具即推翻「注解过滤」论)。最终不可观测层 用可执行的对照实验收口(新会话看是否 23/23)。缺的工具找 CLI 等价物 (evolver solidify / evolver hitl list),不阻塞闭环。

18. asset_search 三重检索缺陷(MCP 工具体检,2026-09-05)

  • 症状tool_asset_search("hub retry") 返回空——库里明明有 gene_hub_fetch_resilience 等应命中基因;单关键词却正常。
  • 根因(三面):(1) 整串子串匹配("hub retry" in haystack)——多词 查询需连续出现,必然落空;(2) summary 不在检索字段——而它是 Gene 的 主文本(penalize 查不到 gene_applied_cooldown);(3) signals_match 不入检索(hub_offline 查空)。
  • 修复:token-AND 语义(分词后全命中才入选)+ summary 入 haystack + signals_match 列表拼接 + 结果 description 回退 summary;4 个新测试 钉住(多词命中/多词带噪排除/summary 检索/signals 检索/空查询)。
  • 经验检索工具要用「真实查询语料」测,别只测单关键词。用户自然 输入是多词的;子串匹配对多词静默归零是最阴的假阴性。另:体检时 proxy 路由同名函数是文件名搜索(不同域),勿误伤。

19. 重复固化无守卫(round-12,2026-09-07)

  • 症状:对已固化 run 再调 solidify,会烧完整级联(实测 424s)、以 ok:True 结束且追加一条幻影 success 事件——验收门 soak 样本被无意义 gated run 污染(verdict=ready 的输入!)。
  • 修复last_solidify.run_id == last_run.run_id 时早退 already_solidified(next_action=swarm_tick);新 dispatch(新 run_id) 永不受阻。
  • 连锁:守卫上线即被级联两次拒绝——test_acceptance_shadow_lineage 的谱系链测试靠「同 run 固化两次」造事件链,与守卫冲突。按生产事实修 测试:链跨 run 生成(每次 tick 新 run_id)。
  • 经验守卫落地时必须全文检索依赖旧行为的测试——级联两次在同一 位置拒绝,正是门在工作;「闪失」判断错了,位置取证(收集序 #204)才是正解。

20. 悬案告破:legacy 回滚 cwd 缺失,级联中删真实运行态(round-12 起,round-13 定罪)

  • 现象:solidify 级联失败 → 回滚后 evolution_solidify_state.json 消失 (round-12 复现两次,round-13 判决实验第三次)。已排除:stash(文件被 gitignore 覆盖)、选择性删除(--exclude-standard 令其不可见)、tick、 失败路径全部六个调用者逐一点名——全数清白。
  • 真凶(syscall 级铁证):legacy 验证失败路径 rollback_new_untracked_files(git_list_untracked_files(cwd)) 漏传 cwd=cwd(solidify.py:965;cli.py:1249 同款)。列表取自隔离 workspace(相对路径 memory/evolution/evolution_solidify_state.json), 删除却回退 Path.cwd()——级联 pytest 从真实仓库根启动,相对路径拼真实 根 = 删中真实运行态。每次级联必中(派发先写状态文件):成功路径随后 重写状态文件掩盖删除,失败路径不重写 → 文件失踪。round-9~12 全部现象 (只在失败后现形、三嫌犯全清白)由此完全和解——删除发生在级联 pytest 子进程内部,仓库内实验天然不可见。
  • 修复:两处补 cwd=cwd(对齐 Sprint 23 在级联处理器已有的显式 cwd 模式);回归测试复现几何(chdir 第二临时根 + 同名受害者文件 + 断言 幸存),负向验证通过(还原 bug 行 → FAILED)。
  • 经验(1) 「列表在 A 域取、删除在 B 域执行」是相对路径 API 的经典 错位,修复模式是让同一 cwd 贯穿 list+delete。 (2) 悬案侦破的武器升级链: 逐文件 bisect → 进程内看门狗(1ms 轮询抓栈,漂移会冤枉无辜)→ 删除型 syscall 间谍(确定性但漏子进程)→ chflags uchg 不可变标志做蜜罐 (删除必 EPERM,间谍在调用前记栈,异常吞不掉)。(3) 全量测试套件在真实 仓库跑时,套件本身就是「未隔离副作用」的携带者——排障时把测试进程当成 嫌疑人之一。

21. paths.py 诊断打 stdout,CLI --json 契约全破(round-13)

  • 症状uv run evolver gate-report --json | python3 -m json.tool 崩 (JSONDecodeError)——stdout 前面混着两行 [paths] Using host git repository at: ...
  • 根因get_repo_root() 用裸 print() 向 stdout 打诊断(两处)。 库层路径解析的副作用污染所有 CLI 动词;EVOLVER_QUIET_PARENT_GIT 旋钮 是事后绷带,通道纪律从未修。
  • 修复:两处 print(..., file=sys.stderr);回归测试断言 stdout 空、 诊断在 stderr。端到端验证 --json | json.tool 恢复可解析。
  • 经验JSON 动词的 stdout 是契约;库层禁止向 stdout 打诊断——与 MCP stdio 的 stdout 纪律(#16 同源)互为镜像。发现即修通道,别加旋钮。

22. 级联在宿主残废 PATH 下验证 + 证据只存头 2000 字符(round-13)

  • 症状:round-13 固化级联 validation_failed(score 0.6667),变异在 开发 shell 下全绿(本地重放 3498 passed);证据文件里 pytest 输出止于 51%,失败名单缺失。
  • 根因(两层):(1) MCP 服务器由 GUI 应用拉起,继承 launchd 精简 PATH(无 homebrew);级联子进程照单全收,测试内 shell 出去的工具 FileNotFoundError——验收门在量宿主环境,不是在量仓库(env -i PATH=/usr/bin:/bin 精确复现 2 failed;全量 8-10 失败为环境差异族)。 (2) _run_validations 只存 stdout[:2000](头部切片)——pytest 失败 摘要在末尾,全丢;连 _parse_pytest_rate 都读不到 N passed (0.6667 = rate=None 的旁证)。
  • 修复_validation_env()(venv bin + /opt/homebrew/bin + /usr/local/bin + ~/.local/bin 前插,只增不删,存在才插)+ _bounded_output()(头 1200 + 尾 2800 + 截断标记)。靶向验证:同款 残废 PATH 下此前失败文件经真实 _run_validations 路径 15 passed。
  • 经验(1) 门的公信力 = 环境规范化——gated 判定混入宿主环境变量 时,soak 样本全部失真;GUI 拉起的 MCP 宿主是残废环境的头号来源。 (2) 证据保留必须偏尾——失败诊断永远在输出末尾;头切片证据等于让门 失败时自我致盲。

24. preflight 负载阈 1.5 平坦常数,多核宿主永久被拦(round-14)

  • 症状:无人值守 tick 在 10 核 Mac 上每次 preflight abort(环境 负载 2.2-2.8 > 1.5)——round-6~13 全靠手工 EVOLVE_LOAD_MAX=8 绕行; 守护循环 --loop 在此宿主形态下根本跑不起来。
  • 根因get_default_load_max() 对多核一律返回 1.5(Node 遗产常数)。 load1m 是运行队列深度,随核数缩放:10 核机上 2.8 的环境负载只占机器 容量的四分之一不到(GUI 常态),却被当成过载。「机器忙时不进化」的 守护本意被扭曲成「GUI 活跃时不进化」。
  • 修复:CPU 感知默认值——队列深于核数才拦(max(1.5, cpus);单核 保持 0.9),EVOLVE_LOAD_MAX 仍是显式覆盖。自证:环境负载 1.87、无 任何覆盖跑 evolver run → 零 abort 正常派发(此前每轮必 abort 的同一 命令)。回归测试钉公式(1→0.9、2→2.0、10→10.0)+ 环境 2.8/10 核 放行。
  • 经验可移植阈值不能是平坦常数——量纲随硬件缩放的指标(load、 IO 深度)必须归一到硬件容量再比较。修完的验收标准是「在出问题的 机器上、不带任何绕行,原命令跑通」。

25. 验收门饥饿:PATH 盲区 + 全量 argv 单超时(round-14)

  • 症状:round-14-A 固化成功但 gated_runs 卡在 13 不涨;翻 round-13 事件发现门的 candidate_repeats 全是 score 0.0, denominator 3527, baseline.json 从未存在过——soak 的 interception 0.0 不是运气好,是 门从未量到过任何东西
  • 根因(三环链):(1) t0_frozen.py 用裸 "pytest" + 无 env= 起 子进程——GUI 宿主残废 PATH 下 FileNotFoundError,gate_or_none 吞异常 返回 None → 事件无 acceptance_result → 计数不涨(round-13 的 _validation_env 只修了级联,漏了门自己的子进程——同类缺陷第二 现场)。(2) run_pass_rate 把全部 ~3.5k 个 node ID 塞一个 argv、共用 一个 120s 超时——套件实际 ~130s+,每次必 TimeoutExpired → (0, 3527)。 (3) should_persist 要求 candidate_mean > 0——0 分永不满足,baseline 永不落盘,每次都走「首次建立」,0.0 对 0.0 = unchanged = 全放行。
  • 修复:提取共享 gep/validation_env.py(级联与门同源消费; solidify 留薄别名);run_pass_rate 按 400 ID 分块执行(argv 有界、 单块 ~20s 远低于单块超时;逐块超时/OSError 记该块 0 分,fail-safe 方向不变)。首次真实测量:3530 ID、352s、candidate_mean 0.8861 (两次 repeat 完全一致),baseline.json 首次落盘(0.886)。
  • 经验(1) 「门从未拒绝」与「门从未测量」不可区分时先怀疑后者—— 全零分 + 分母满额 + 基线永不存在,就是测量路径死的自画像。 (2) 子进程 spawn 点是环境缺陷的复利面:每新增一个 spawn 点都要过同一个 env 规范 化助手,别让修复只覆盖第一个现场。 (3) 大集合过单一超时预算 = 必超时, 分块让预算与工作量同尺度。 校准余项(留给人类):分块显式枚举绕过 级联的 -m "not slow" deselect,干净树测得 0.886 而非 ~1.0——回归地板 的一致性(基线与候选同尺同测)已保,绝对分口径是否对齐级联由人定。

26. T0/级联种群错位 + 未隔离管线测试污染真实运行态(round-15)

  • 症状(双线):(1) round-14 门首次真实测量干净树只得 0.8861——402 个「幻影失败」。(2) 取证中撞见真实 evolution_solidify_state.json 持有 测试夹具数据(run_id r1、gene g2/g3),且 soak 样本里混着一个 r1/g3 SUCCESS 幻影事件(带 acceptance_result,计入样本)。
  • 根因(双定罪):(1) 分块级重放把 402 精确分解:chunk6(ID 2400-2799)单块 120s 超时整块 400 归零 + chunk0 两个 llm e2e(无 DEEPSEEK_API_KEY)+ chunk5 跑 112.2s(差 8 秒的超时抖动源)——冻结集 含 slow 标记测试,而级联自身 -m not slow 会 deselect:门在量一个 比已验证它的门更慢的种群。(2) 逐测试哨兵插件(状态+事件双监视器) 定罪 test_dispatch_constrained.py::TestDispatchConstrainedHook 五个 测试——无隔离直呼 dispatch_phaseround-11 把 dispatch 状态写入改 无条件后它们变成污染者:成功固化的收尾重写掩盖垃圾,失败固化把 r1 留在盘上(幻影 pending)。修复后哨兵套件双零命中;幻影事件向量在 当前代码下已不可复现。
  • 修复:T0 发现对齐级联 -m "not slow"(3505 ID 完全一致;块耗时 全部远离预算,慢测试不再从门内对活仓库执行);五测试加 autouse temp_workspace;清除 1 个幻影事件;baseline 重置(种群变更)。round-14 留给人类的口径问题由此以「缺陷」定性收口:错位不只是口径——它同时是 超时噪声源与状态污染面。
  • 连带失误(自伤,入册示警):哨兵探针把 tick 已派发的真实 run 状态 整个换成 marker,固化消费了垃圾状态(事件谱系手术修复);MCP 进程早于 round-15 编辑,固化用旧发现逻辑重测旧种群、重落旧哈希 baseline(再次 清除)。
  • 经验(1) 门与级联必须同种群——回归地板量「另一个宇宙」时, 绝对分、超时行为、副作用面三者同时失真。 (2) 管线阶段测试(会持久化 状态者)一律请求隔离 fixture,哪怕只断言提示词块;把「写入变成无条件」 的修复要全文检索谁在裸跑该管线。 (3) 取证探针是破坏性操作:跑前快照、 跑后重派发;改码后驱动代码敏感的 MCP 工具前先看 code_staleness

方法论沉淀

  1. 覆盖审计先行pytest --cov 找冷分支再补测——#9 由审计钓出,非偶然。
  2. 实证闭环:每修必跑「根因场景」对照(设标志/造输入 → 修复前后行为差); 改了但没生效时,怀疑注入链上有 flag/噪音两层。
  3. 静默降级是头号嫌疑:skip/unvalidated/empty 且无指引的路径,六个 bug 里 四个(#2/#6/#8/#10)生于静默。
  4. 真仓即试验场:dogfood 让 #1/#4/#5/#7 只可能在真实运行中现形——单测全绿 不等于引擎能用。
  5. 转达不是批准:MCP 上的「人类」工具与申请者同一进程时,必须 fail-closed 或切断(#12)。提示词政策挡不住无人值守。
  6. 剧本 ≠ 落地:选择器选出的基因 id 不是工作区里实际写下的基因 id(#13)。 提交、冷却、创新日志必须同时记下两者。
  7. 测试工具先于被测物:「协议面过、数据面一刀切全挂」先查探针解包/断言 (#14/#15);写断言前先 raw dump 一次真实响应,别凭记忆写键名。
  8. 长驻进程的重载语义:stdio MCP server 只在 spawn 时载入代码——改码后 重连才生效;会话中途加的配置要新会话才加载(#16)。
  9. 三层排查:配置层 → 服务端层 → 客户端组装层,逐层证明干净再上移; 不可观测层用对照实验收口,缺的功能找 CLI 等价物绕行(#17)。

27. 新增源码型资产只跑靶向检查就提交(round-16)

  • 症状:round-16 固化连续两次被级联拒绝——第一次 ruff 段(锚探针源 src/evolver/assets/anchor/*/probe.py 13 处 I001 import 排序 + 2 处 E501), 修后第二次 mypy 段(8 个同名 probe.py__init__.py → duplicate module, mypy src 全扫即炸)。两次拒绝全部正确;缺陷在我:提交 P0 前只对新建 模块跑了靶向 mypy <file> 与靶向 ruff,没跑级联的原始三段命令
  • 根因:全量 pytest 过了(pytest 不扫 assets 下的 .py),造成「已验证」 假象;靶向检查 ≠ 级联检查。锚探针是「源码型资产」——住在 src 下、被 ruff/mypy 全扫视作源码,却按资产语义(独立脚本、重名by设计)运行。
  • 修复:探针 ruff --fix + format;pyproject.toml [tool.mypy] exclude "src/evolver/assets/"(独立脚本不做模块同一性检查;其正确性由锚套件 自身在运行时执法);修后以级联原始命令ruff check src tests + mypy src)复验;epoch 2→3 重装锚目录同步冻结字节。第三次固化一次 落齐 13 文件,锚首次生产触发 8/8、计时首落、baseline 齐平种群重建 0.9997。
  • 经验提交任何新增 .py(尤其源码型资产)后,验证标准是级联的 原始三段命令,不是靶向检查——靶向过 + 全量 pytest 过仍可能 ruff/mypy 全扫炸。另:连续失败的回滚 stash 会把未提交的修复一并卷走,恢复清单 要含修复文件而不只是变异文件。**

28. stale 宿主惰性导入裸崩 + 工具目录暴露于回滚处置(round-17)

  • 症状:round-16 实况——长驻 MCP 进程在引擎改码后,swarm_tick/ swarm_distill 直接返回裸 ImportError("cannot import name 'ANCHOR_PROBE_TIMEOUT_S'"):进程内存持有旧 config,惰性导入磁盘上的 新 solidify→anchor,新旧模块链拼接即炸;宿主拿到栈回溯而非可行动 错误。另:.mimosa/.video_agent/ 等宿主工具目录未跟踪——级联 失败回滚会把它们当「可弃未跟踪文件」删除。
  • 根因_swarm_tick_locked 的 except-Exception 只盖 run_cycle, 盖不到 tick 序言导入与 distill 深层安装路径(record_landed_gene_ids 的惰性导入);回滚的 --exclude-standard 只豁免 gitignore 路径, 未知未跟踪目录按变异残留处置(对变异残留是对的,对工具目录是误伤)。
  • 修复_stale_import_error()error=code_stale_process + next_action=reconnect_host + hint;三处守卫(tick 序言、run_cycle 分支先于 cycle_crashed 分类、distill 安装路径);三个回归测试 (monkeypatch raiser)。工具目录入 gitignore——ignored 路径回滚豁免、 变异残留照旧可弃,语义各归其位。
  • 经验长驻进程的每个惰性导入面都是版本混拼断点——守卫要盖 序言与深层调用路径两处;「未跟踪 ≠ 可弃」,回滚处置以 gitignore 为 声明边界。 里程碑:本轮门完成首次「候选 vs 基线」比较 (t0_only_no_regression,0.9997==0.9997 unchanged 接受)——回归地板 全链路运转。

29. meta-report transfer 维度两度过松:常驻信号头背景虚报「迁移」(round-18)

  • 症状evolver meta-report 的 transfer 面板(Table-8「迁移性」维度)对 live 数据报出 2 个「多信号族复现」基因;取证发现全部 12 个成功事件携带的 触发信号头集合几乎相同——autopoiesis:*preflight_abort 等常驻背景 头在每个事件都在,基因跟随事件重复出现即被旧口径(头集大小 >1 / 两事件头集 不等)计为「跨情境迁移」。第一版收紧(两事件头集不等才算)仍有 2 例假阳: 事件间 boilerplate 信号头的微小增删即可让头集「不等」。
  • 根因「跨情境复现」类指标直接比较原始观测集,没有剥离常驻背景。 背景(几乎每事件都出现的信号头)与信号(仅特定情境出现的头)混在同一集合 里,集合比较的任何变体都会把背景微变误判为情境差异。
  • 修复meta_report.py transfer 改为差分头集口径——先统计每事件触发 信号头集合,凡出现于 ≥50% 事件的头判为公共头(common_heads)排除;每事件 取 heads - common_heads 为差分集;仅当同一基因在 ≥2 个事件出现且差分集 存在 ≥2 个互不相同的非空取值才计迁移(live 诚实归零)。负例测试 test_transfer_requires_differing_head_sets:公共头-only 重复不计、 差分头真异才计。
  • 经验凡「跨情境复现/迁移/泛化」类指标,必须先估计背景分布再比差分 ——直接比较原始集合,测到的往往是背景噪声的漂移而非信号本身。诚实归零 优于体面的虚报:structural-L5 审计的目的是暴露真实水位,不是装点它。

30. 效率维度混合种群平均 + 失败事件验证成本零痕迹(round-19)

  • 症状evolver meta-report 效率面板 live 报 28,226 ms validation/gain; 取证计时种群内真实成本 178,765 ms(6.3 倍低估),且覆盖率仅 3/19——14 个 round-16 之前的 accepted 事件无 validation_timing,稀释了分母。另: round-16 两次级联拒付(各烧一整轮验证)在事件上零成本痕迹——效率维度对 最贵的路径全盲。
  • 根因ms_per_gain = sum(计时事件)/len(全部 accepted)——分子分母种群 错配(#29 的对偶:#29 是观测集混背景,本条是比率两侧不同群);且 validation_timing 只在成功事件构造(round-16 只挂了成功路径),失败事件 走 _failure_event 骨架不带计时。
  • 修复:(1) meta_report.py 分母改计时种群内 accepted 数,分子含失败 事件的计时(拒绝的级联同样烧秒),面板新增 timing_coverage (timed_events/timed_accepted/accepted_total)暴露样本代表性;CLI 效率行 附 (timed M/N accepted)。(2) solidify.py 提取 _timing_block() 助手,_failure_event 增可选 validation_result 参数——级联失败/legacy 失败/anchor 失败/验收门拒绝四条路径全部挂 validation_timing。live 修正为 178,765 ms/gain。负例测试:无计时样本不得稀释分母、计时失败进分子不进 分母。
  • 经验比率型遥测的第一审计问题是「分子与分母是否同一种群」; 成本可见性必须覆盖所有终点(失败是成本大头——只记成功样本的效率面板 系统性乐观)。后续发现(本轮回填):本轮固化实况暴露 time.time() 挂历时钟陷阱——固化期间本机系统睡眠 5.1 小时整段计入 pytest 时长 (真实 ~208s 记成 18,349s,88 倍),时长测量必须用 time.monotonic() (round-20 修)。

31. 时长测量用挂历时钟:系统睡眠整段计入验证时长(round-20)

  • 症状:round-19 事件 validation_timing.total_ms = 18,348,987 (≈5.1 小时),但该次固化墙钟窗口内宿主只观察了 ~14 分钟轮询。
  • 根因_run_validations 的总时长与逐段 duration_ms 全用 time.time()——挂历时钟吸收系统睡眠与 NTP 步进。固化期间本机睡眠 5.1 小时(事件 ts 18:58Z=本机 02:58 vs 启动 21:44,虚增秒数与睡眠 窗口精确吻合),整段计给了 pytest 段。round-16 引入计时以来第一次 睡眠撞上固化,即刻现形。
  • 修复:时长源改 time.monotonic()(睡眠免疫、单调);顶层新增 duration_ms(单调测量);_timing_block 优先取之,legacy 无字段 事件回退挂历差。started_at/finished_at 保留挂历 epoch——它们是 ValidationReport 的时间戳契约,语义是「何时」不是「多久」。回归测试: 单调时长 ≤ 挂历跨度+舍入容差;伪造 9e6ms 挂历污染不得覆盖 5ms 单调值。
  • 经验时间语义二分法——时间戳(when)用挂历 epoch,时长 (how long)必用单调钟。长驻进程(守护、MCP 宿主、固化)在笔记本电脑 上合盖即睡,挂历差会把分钟级操作记成小时级;效率/性能类遥测的第一 个审计问题就是「你的分子是哪个钟量的」。append-only 账本不改史:污染 事件留档,新样本累积后指标自愈。

32. 验收门 layer_id 前缀翻倍 + soak 判定 false_kill_high(round-21)

  • 症状:事件持久化的验收层 id 形如 T0_frozen@T0_frozen@b50bcb4c… (前缀翻倍);同轮 soak 判定翻为 false_kill_high(false_kill_risk=1.0)。
  • 根因(layer_id)solidify_hook 把上一轮的 t0_layer.layer_idT0_frozen@<hash>)存进 baseline.jsont0_snapshot_hash 字段; 下轮 orchestrator 读回作 snap_label,组装处 f"T0_frozen@{snap_label.removeprefix('t0_')}" 只剥小写 t0_ 词干 (对应快照文件名 t0_<hash>),对已带 T0_frozen@ 前缀的存档值无效 → 每个比较周期前缀翻一倍。unchanged 判决不重存基线,故停在两倍; 一旦 improved 会把翻倍值再存档并向三倍演化。
  • 修复_t0_layer_id(snap_label) 规范化助手——剥 T0_frozen@t0_ 两种拼写(兼容裸 hash)后组装 T0_frozen@<hash>;establishing 与 comparison 两处组装点共用。三测试钉住三种输入拼写归一。
  • 经验标识符组装的输入有两种来源拼写时,组装点必须先规范化再拼 ——「把组装产物存进原始值字段」是往返腐蚀的经典通路,读回再组装即翻倍。 soak 头号发现(本轮另一线):gated 20/20 达标,但 T0 repeat0 测 0.8863 / repeat1 0.9997——0.886 即 #25/#26「分块超时→整块归零」旧签名, 同轮级联全绿、变异仅改 id 字符串,纯测量噪声伪杀;interception=0.05 踩线、false_kill_risk=1.0 如实报告。结论:门过紧未到转正水位, 校准方向=分块超时单块重试 + 重复间方差异议裁决(下轮候选)。soak 的价值正在于让伪杀在 shadow 里现形,而不是在硬执法里杀掉好变异。

33. 门噪声免疫(分块重试 + 方差异议裁决)+ preflight 测试未隔离 user-lock(round-22)

  • 症状:#32 伪杀根因双修 + 一次「级联正当拒绝」。round-22 首次固化 validation_failedtest_ambient_load_below_cores_passes_preflight abort 于 user lock active (lock_active, age=37317ms)——真实守护进程 (evolver --loop)持有的 ~/.evolver/user.lock 被测试读到。
  • 根因:(A) t0_frozen.run_pass_rate 每块 TimeoutExpired/OSError 直接 continue——瞬时负载尖峰令 400 ID 计零(0.886 签名);重复观测 无条件进均值,单次抖动即可把均值拖成 dropped。(B) 该 preflight 测试 stub 了 CPU/负载却没隔离锁路径(#4 家族)——eval worktree 隔离了文件、 隔离不了 env 键控的宿主态,守护进程持锁时必炸;活树跑时此前靠运气 (锁不存在或已过期)。
  • 修复:(A) 分块失败重试一次(_CHUNK_ATTEMPTS=2),二次失败保持 fail-safe 计零;orchestrator._adjudicate_flakes——重复极差 > T0_FLAKE_ADJUDICATION_SPREAD(0.05,config 常量非 env 旋钮)时追加 一次仲裁 repeat 取中位数,偏离中位数超 spread/2 的观测写入 LayerMetric.adjudication(trimmed-not-hidden)后移出均值;一致低分 (真回归)不触发裁决照拒;establishing 模式同过裁决(基线被单次抖动 打低会让后续轮全读 improved)。(B) 测试 EVOLVER_USER_LOCK 指向 tmp 不存在路径,在守护进程持锁实况下验证绿。
  • 经验校准只治噪声、不放宽标准——负例测试钉住「一致回归仍被拒、 一致重复零额外开销」是这类修复的验收面;隔离测试要覆盖全部被读的 状态维度(stub 了 CPU/负载却漏了锁,等于没隔离);干净 worktree 会 把 env 键控的宿主态泄漏照出来——那正是它的职责。另:级联的正当拒绝 → stash 恢复清单含修复文件 → 重固化通过,闭环在诚实工作;首个带计时 的失败事件(168s)入账,#30 的失败成本可见性兑现。

34. 遥测仪器自外于治理 + 失败事件隔离元数据缺失(round-23)

  • 症状:RSI 审计 5.3-3/6.5 两项——(1) ops/meta_report.py 既不在 ANCHOR_TRIGGER_SURFACES 也不在机制面:round-18/19 的遥测变异不触发 锚、不计 structural-L5,而连续三轮修的都是「表」的诚实性(#29/#30/#31) ——米尺自己不在被审计之列;(2) 失败事件只挂 timing 不挂 eval_workspace ——round-22 被拒事件无法自证跑在干净树上,被拒证据链比接受事件短。
  • 根因:治理面清单按「验证器+守卫」枚举时漏了测量仪器(它不判接受, 但它喂给人看的一切数字);_failure_event 骨架在 round-19 只补了 timing 一个字段。
  • 修复:(1) meta_report.py 入 ANCHOR_TRIGGER_SURFACES(机制面经展开 自动含之);锚 epoch 4 新增第 9 探针 telemetry-invariants——合成 事件集上冻结三条不变量(比率分子分母同计时种群+覆盖率、transfer 常驻 头排除后差分集才计迁移、_timing_block 优先单调时长忽略挂历污染)。 (2) _failure_event 增可选 eval_meta(flag_off/skipped 过滤与成功 路径逐字一致),级联/legacy/anchor 三条拒绝路径传参。
  • 经验米尺是改进机制的一部分——凡「喂给人做决策的数字」的生产 线,其变异都该触发锚并计入机制审计;失败事件的证据链字段必须与 成功事件同构(差一个字段就是下一轮的取证盲点)。探针工程三条: 小样本统计规则的夹具要避开阈值边界(≥50% 公共头规则配 4 事件平衡 分裂必撞,改 5 事件 3/2 几何);断言必带消息(空消息让定位多绕两轮); 读真实 anchor 目录的测试必须用隔离夹具。

35. soak 判定全历史窗口:校准前的伪杀永不过期(round-24)

  • 症状:round-22 已落地门的噪声免疫校准,但 soak 判定持续 false_kill_high——取证 summarize_acceptancefalse_kill_risk = 分歧/拒绝 作用于全部历史 gated 事件,round-21 校准前的伪杀分歧 永不滑出统计。要稀释到 ≤0.1 需再攒约 9 次「门与级联一致的拒绝」 ——即故意喂坏变异,判定修复路径本身 perverse。
  • 根因:soak 指标无窗口概念。「校准后的门是否够格转正」这个 问题问的是近期行为,全历史口径把校准前的债永远记在校准后的门上 (#30 的第三形态:比率的两端不仅要同种群,还要同期)。
  • 修复summarize_acceptance 增滚动窗口——默认取最近 GATE_SOAK_MIN_RUNS(20) 个 gated 事件(时间戳稳定排序取尾), 样本不足窗口全量(收集期语义零变化);metrics 增 window_runs、 CLI 文本附 (rolling)。四测试钉住:校准前伪杀滑出→false_kill 归 None(不赖账);近期伪杀照计(不遮丑);不足窗口全量;显式覆盖。
  • 经验校准类指标的证据必须滚动——修复前故障随窗口自然 过期,否则唯一出路是制造分母。live 验证即本条的最佳注脚:窗口 生效后 round-24 自己的固化又暴露下一层校准债——T0 repeat0 恰好少 1 个测试(3517 vs 3518/3519,极差 0.00028 ≪ 0.05 裁决阈) 未触发仲裁即判 dropped。冻结集是确定性的:重复间任何差异都是 噪声,裁决触发应粒度感知(重复不一致即仲裁),而非固定大极差 ——round-25 的种子。另:本轮固化期间系统又睡眠 ~40 分钟,单调钟 计时 269s 未受污染(#31 兑现)。

36. 裁决粒度盲区:固定大极差阈放行单测试噪声(round-25)

  • 症状:round-24 的 T0 repeat0 比 repeat1 恰好少通过 1 个测试 (3517 vs 3518/3519,极差 0.00028 ≪ 0.05 裁决阈)——仲裁未触发, 单测试抖动把均值拖成 dropped,第二个伪杀样本入 soak。
  • 根因:#33 的裁决触发用固定大极差阈值(0.05,为大块归零 0.886 量级设计),但 T0 冻结集是确定性套件——同 ID 同树的 重复应当完全一致,重复间任何差异都是测量噪声,不存在「合法 的小差异」。阈值逻辑错用了随机性测量的统计框架去套确定性测量。
  • 修复_adjudicate_flakes 触发改为「重复分数不完全一致即 仲裁」;仲裁后多数值(mode)锚定——等于多数值的观测保留, 少数侧 trimmed-not-hidden 入 adjudication(counts/majority_score 全暴露);无多数(三值互异=持续抖动)保守保全全部(fail-toward- reject)。大极差伪杀与单测试伪杀统一走同一机制; T0_FLAKE_ADJUDICATION_SPREAD 常量退役。真回归路径不变:重复 一致低分照拒。
  • 经验确定性测量的仲裁不需要统计阈值——重复间任何差异 即噪声,应即触发并以多数值锚定;阈值只属于随机性测量,先问 测量物是否确定再选框架。粒度单测(3519 分母单测试差异)与无多数 保守测试钉住两个方向。校准瀑布至此三层(块级 #33 → 窗口级 #35 → 粒度级 #36):本轮 T0 双重复干净一致、裁决零打扰——接近收敛。

37. 测试泄生产 wiki + set_flag 进程内泄漏(round-26)

  • 症状:(a) 生产 wiki/skill-impact.md 161 条中 128 条(79.5%) 是 fixture 噪声gene-1/log_error/0.98 逐字段吻合测试夹具)—— dispatch 提示词的「勿重复」记忆被噪声淹没,实质失效;每次全套件 跑泄 3-4 条(级联 1 + T0 双重复 2-3)。(b) test_solidify_fitness.pytest_wiki.py 相邻同进程跑必红(test_solidify_shadow_rejection_ lands_impact_entry 丢条目),反序/单跑/全套件(文件间隔)皆绿—— stash 验证为预存顺序缺陷。
  • 根因:(a) test_failed_event_appended_with_score 驱动真实 _handle_cascade_validation_failure,stub 了事件/回滚/状态五个 函数却漏 _wiki_rejection,且未请求 opt-in 的 temp_workspacewiki_dir() 落到真实 memory/evolution/wiki。#4 家族第 N 次: stub 五漏一。(b) set_flag(persist=False) 改进程内 _disk_flags 缓存无撤销——flag 测试把 enable_fitness_cascade=False 泄给 后续测试,wiki 测试走 legacy 路径无测量无 no_improvement 无条目。
  • 修复:(1) 泄漏测试补 temp_workspace;(2) conftest 会话级 tripwire——快照真实 skill-impact.md 条目数、收尾断言不变(泄漏 即红且报修法;刻意不 redirect——env 驱动的 wiki 测试自管路径); (3) conftest autouse flag 快照恢复——对进程内 flag 缓存做 monkeypatch 之于 env 的等价物;(4) 运维清创 128 条噪声(wiki 自有 审计 git 提交)。生产实证:修复后固化期间全套件 3 跑,wiki 仅 +1 正当条目、噪声零增长。
  • 经验逐测试手工隔离纪律必然有洞——洞用套件级机械防线兜底 (tripwire + 快照恢复),不是更仔细的人。顺序敏感的绿(单跑绿/ 全套件绿/相邻红)本身就是缺陷信号:说明行为依赖了同进程前任测试 的残留。会话 tripwire 的判据要选「只增不减」的单调量(条目数), 误报率零。

38. 门校准语义无仓外冻结:验证者相邻不变量只受可同谋测试保护(round-27)

  • 症状:rounds 22-25 建立的验收门噪声免疫三件套——run_pass_rate 分块超时恰重试一次(#33)、summarize_acceptance 滚动 soak 窗口 (#35)、_adjudicate_flakes 多数值仲裁锚定(#36)——全部只受仓内 tests/ 保护。而 acceptance/ 全目录已在锚触发面(ANCHOR_TRIGGER_ SURFACES),理论上锚该兜底;但锚探针只覆盖旧语义(population parity / validation env / telemetry),三件套语义无一冻结:一个同时 弱化门与其测试的变异,会被被弱化的测试放行,锚亦无从比对—— 自举盲区:验证者相邻语义不能只由「同一变异可以一并改掉的测试」看护。
  • 根因:锚 epoch 4 的 9 探针冻结于 round-23(telemetry 三不变量), 其后 rounds 24-25 又落了两层新校准语义(滚动窗口、多数值仲裁), 均未推进 epoch——「修完即锚」的纪律在连续快速迭代中被跳过,累积成 两层无仓外冻结的窗口。
  • 修复:锚 epoch 5 新增第 10 探针 case-gate-calibration-invariantssrc/evolver/assets/anchor/,214 行纯进程内)冻结三条:(a) 滚动 窗口——25 事件最旧位伪杀滑出归 None、最新位照计 1.0、默认钉死 GATE_SOAK_MIN_RUNS(env 钉在首次 evolver 导入前,免环境漂移); (b) 多数值仲裁——3519 分母单测试差异触发、恰一次仲裁重复、少数侧 进 info["trimmed"] 记录不隐藏、一致重复零打扰、全异值保守全保留; (c) 分块恰重试一次——首试超时次试通过计全分、二次失败保持计零、 无第三次调用。仓内加 test_seed_suite_includes_gate_calibration_ invariants 种子守卫。双家验证:tmp 家 epoch 1 + 真家 epoch 5 各 10/10;引擎自提交 f3cefb5
  • 经验验证者相邻语义(带否决权的测量/校准逻辑)落地的同一轮 就该推进锚 epoch——「下一轮再锚」会累积成自举盲区。探针冻结的是 可观察契约(输入合成事件/monkeypatch 边界),不冻结实现;env 派生 常量须在探针进程首次导入 evolver 前钉死。仓内种子守卫测试防「探针 被从种子里静默删除」,仓外冻结防「测试与实现同谋弱化」——两层各管 一边。

39. 幻影 preflight-abort 快照:测试泄漏的信号操纵蜂群选择器(round-28)

  • 症状:round-27 tick 的信号列表持续携带 preflight_abort / autopoiesis:preflight_abort / preflight_abort:test_abort 三信号, 上下文行「resolve blocker (test abort) before innovate」、repair 偏置与 Hub 跳过常驻——但近 9 轮全部成功固化,并无真实阻断。磁盘 memory/evolution/autopoiesis_preflight_abort.json 存在且 reason="test abort",时间戳恰落 round-27 固化级联的 pytest 段内; 该 reason 字符串全仓唯一出处是测试 fixture。
  • 根因test_runner_preflight_abort_attaches_report 只带 monkeypatch 无 temp_workspace,驱动真实 _run_single_cycle 的 abort 路径——run_preflight_abort_self_reportpersist_preflight_abort_report 无条件落盘(生产语义:降级 周期也要暴露 abort,EVOLVER_AUTOPOIESIS_WRITE 只管 SelfReport 自身) ;而 runner 的 abort 路径提前 return,永不到达周期末的 clear_preflight_abort_report,测试也不清。每次全套件跑后真实 运行态留下幻影,后续所有周期经 preflight_abort_signal_keys() 读到即注入信号与偏置。#37 家族第三例(wiki→flags→abort 快照)。
  • 修复:(1) 该测试补 temp_workspace + 断言快照落沙箱(并注明 abort 路径为何到不了 clear);(2) conftest 会话级 _phantom_abort_snapshot_tripwire——收尾时真实快照若存在且 reason 为已知 fixture 串即红;按 reason 判红而非按存在性(守护进程 合法写真实 abort:load/lock/release-window——存在性判红必误报); (3) 清理现场幻影。清后即时证伪:round-28 tick 信号列表干净、 adaptive 模式从 explore_plateaubalanced。负向验证:植入 fixture-reason 快照→会话收尾 AssertionError(消息含修法)→清理。 引擎自提交 90e8387附带:本环首次环境性级联超时拒绝—— 宿主开会(腾讯会议 151% CPU,负载 154)把 eval worktree 的 pytest 拖过 600s 线,validation_failed 诚实落账(级联红=非伪杀,不污染 false-kill 口径);负载回落后 stash 恢复重固化即绿。
  • 经验带持久化副作用的提前返回路径是测试泄漏的高发面—— 测试作者看得见「调用了被测函数」,看不见「周期末还有个 clear 在 别处等着」。tripwire 的判据要选「生产写手写不出来的值」(fixture reason 字符串),而不是「文件存在」——凡是守护进程/生产路径会 合法创建的同名工件,存在性判红都是误报机器。宿主环境过载导致的 级联超时是环境事实不是变异缺陷:等负载、恢复、重固化,不改编 timeout。

40. shell 模板执行器:原始占位符值即注入面(round-29,Mimosa triage)

  • 症状:Mimosa 深扫(25 findings)报 gep/llm_template.py:80 命令注入。人工审定为真实但潜伏run_external_template 将 占位符值替换进 shell=True 命令串执行,值含反引号或 $( 即 命令替换执行。当前零生产调用方(enable_llm_template 默认关、 无模板配置),但模块是文档声明的 B1/C2 LLM 调用机制——接线后 占位符值将是诊断 prompt(运行态日志 + Hub 派生文本),半信任 输入直入 shell。
  • 根因render_template 的设计只防 ARG_MAX({<name>_file} 把大 prompt 落盘传路径),未防注入——防的是「太大」不是「太恶」。 其余 24 findings 判定:4 注入候选中 2 是检测器/沙箱自身的模式串 (FP)、1 是本地 evolver exec 执行操作者命令(by-design); 11 路径穿越 / 2 SSRF / 5 不安全随机 / 1 资源所有权绑定均按本地 单用户工具威胁模型判 by-design(操作者控制 env/配置即信任根)。
  • 修复run_external_template fail-safe 守卫——被原始替换进 模板的占位符值含命令替换构造即拒绝执行、落 _refused.txt 审计 标记(消息指向 {<name>_file} 正道)、返回空串(与 timeout/ OSError 同契约)。只查 {key} 原生出现在模板中的键(_file 机制入命令的是引擎生成路径,不过 shell 解析器);模板自身的 shell 语法不受限(操作者=信任根)。零新 env 旋钮(soak 章程 纪律),零调用方零破坏。四测覆盖:反引号/$( 拒绝、干净多行 值照跑、_file 通道含反引号文本不受查。全量 triage 落档 docs/mimosa-triage.md(含扫描 seal 与遗留观察)。引擎自提交 44a046f
  • 经验shell 模板执行器必须分治两个信任根——模板语法信操作 者,载荷值永远不信。自由文本进 shell 命令的唯一正道是文件 占位符(引擎写盘、传路径);检测器/黑名单代码里的危险模式串是 扫描器固定误报源,triage 先认模式再谈修复。fail-safe 拒绝优于 转义(shell 转义无法区分 markdown 反引号与命令替换)——拒绝 消息写明正道,操作者可自助换通道。

41. 验收门终态死锁:ready 结构性不可达 + 阶段指标读数饱和(round-30)

  • 症状:round-21 起 gate-report 的 verdict 恒为 false_kill_high;即便 round-22/25 两次校准已消除伪杀的成因、且旧伪杀随滚动窗自然滑出,机器也 永远不会给出 ready——「校准后的健康安静期」的终态是另一个非 ready 判定(旧的 under_intercepting)。同时 gated_runs 自达标之日起恒为 20 (累积实已达 28),阶段进度停止表达,只能靠人肉记忆追 40/42。
  • 根因:三处叠加。① report.py:51 窗口切片 gated_all[-window_runs:]gated_runs 天花板 = GATE_SOAK_MIN_RUNS,metrics 又无累积字段——一个 被用作阶段退出条件的读数,饱和之后就不再是观测口;② 判据缺「门是否真 的判别过」这一维:零拦截既可解释为代码健康,也可解释为从未锻炼过判别力, 无证据时二者不可分;③ shadow_rejected=0 → false_kill_risk=None 使流程 必然落到 interception < 0.05 的最后一支——最坏输入(健康)的落点是 「另一个非 ready」,那不是判据,是死锁
  • 修复:① metrics 增 gated_cumulative(全时段)与 verified_true_positives / verified_false_kills(人工裁决计数,全时段——确认真阳性是耐久证据, 不应随窗口过期);② 判据重排:样本成熟度 → 校准类(false_kill_high / over_intercepting)→ 人工确认真阳性下限(unverified)→ 安静期 (collecting_verified,替掉不可达的 under_intercepting)→ ready。 校准类排在证据完备性之前是因为它们 actionable——「你的门太紧」比「你没 交材料」更该说;③ 人工裁决走仓外只读账本 $EVOLVER_HOME/anchor/gate-verifications.jsonl(与锚同级信任:人写、引擎 永不写;缺文件/坏行跳过而非致命),由 ops/soak_env.read_gate_verifications 喂给纯函数形态的 summarize_acceptance;④ 触 acceptance/ 面 → 同轮升锚 epoch 6,新增探针 case-gate-verdict-reachability 冻结三条不变量(累积 计数必须暴露饱和、无指控绝不给 ready、确认滑出窗口仍解死锁),11/11 探针 通过。零新 env 旋钮,版本仍钉 1.112.0。
  • 经验凡作为「阶段退出条件」的读数,写判据时必须把每个分支的最坏输入 跑一遍——此处最坏输入恰恰是成功(健康安静)。落点若仍是「非 ready」, 则 ready 不可达,整套判据只是记账器而非门。其次,窗口化指标必须同时报 累积值:天花板一到,进度就被迫回流到人的记忆,而人的记忆会漂移(本轮 复核里三处计数偏差全部出自人工核账——包括写下这条经验的 reviewer 自己)。 最后,自动门要证明的不是「它很少误杀」,而是「它真的能动」:二者需要 的证据不是同一个东西,前者是统计,后者至少一次人工确认的真阳性。

42. T0 基线测量不对称:单浮点合成伪观测放行退化或误杀(round-31)

  • 症状:候选侧享有完整的多次重复采样与多数值仲裁防噪保护,但基线侧在 orchestrator.py:221 却直接用历史保存的单个 float 标量合成单条伪观测 ([RepeatObs(index=0, score=baseline_t0_rate)])。历史偶发低基线会 侥幸放行后续退化变异,历史偶发高基线则会恶意误杀合格变异;双侧采样不对称。
  • 根因:历史 save_baseline 仅持久化了 t0_pass_rate 单一浮点标量与快照哈希, 丢弃了候选固化时已测得的多轮 repeat 观测与仲裁元数据;比对时基线无法重构多观测。
  • 修复:(1) save_baseline 支持持久化 t0_repeatst0_adjudicationsolidify_hook 在固化新基线时同步落盘双侧完整观测;(2) orchestrator 支持三级阶梯:baseline_cwd 现场测量 > baseline_repeats 历史观测 > 单浮点标量兼容回退;(3) 触 acceptance/ 面 → 同轮升锚 Epoch 7, 新增探针 case-t0-bilateral-repeats 冻结持久化多观测保真、双侧重复不塌缩 为单点、旧基线优雅后向兼容三不变量,12/12 探针全绿。
  • 经验确定性测量的对比必须双侧对称——不能一侧戴防噪盔甲,另一侧裸奔。 基线不仅是一个静态的分数,而是上一次通过门控时的完整经验观测;持久化时丢弃 观测细节等于强迫下一次比对退化为点估计。

43. 半信任文本入执行面军备竞赛与环境脚印膨胀(round-32)

  • 症状:(1) LLM 模板自由文本替换({prompt}{diagnosis} 等)如果仅靠内容黑名单 过滤,容易遭遇特殊字符、转义字符或编码绕过(军备竞赛);(2) 全局唯一 EVOLVER_* 环境变量 膨胀至 180+,大量内部超时、单例锁目录、废弃探针标记充斥代码,测试隔离负担沉重且运维心智开销极大。
  • 根因:(1) 试图在字符串替换后「检查内容是否安全」,而不是在替换前「判定通道身份是否安全」; (2) 各功能演进过程中习惯性随手引入 os.environ.get("EVOLVER_...") 作为快速配置旋钮, 缺乏常数化与收敛机制。
  • 修复:(1) 在 gep/llm_template.py 中确立「自由文本占位符按身份裸用即拒」机制(FREE_TEXT_PLACEHOLDERS), 凡在 shell 模板中直接裸用 {prompt} 等占位符者一律拒认,阻断黑名单军备竞赛;同时提供自动材料化文件 通道({<name>_file} 自动转为 <stamp>_<name>.txt 绝对路径);(2) enable_llm_template 设锚守卫互锁,并升锚 Epoch 8(新增探针 case-data-ingress-guard,13/13 PASS); (3) 实施 S30.4/30.5 env 退役,将 103 个冗余或内部配置变量折叠为稳定常数或统一已有规范变量 (如 EVOLVER_SETTINGS_DIREVOLVER_LOGS_DIREVOLVER_REPO_ROOTA2A_NODE_ID), 全局独立 EVOLVER_* 从 180 骤降至 77(≤80,charter-check 判定 met=True)。
  • 经验安全边界必须建立在数据通道的类型与身份上,而非文本内容的词法分析上—— 只要自由文本不能进入 shell 解析流,注入漏洞就从数学上不复存在。其次,环境配置不是免费的: 每一个未受管控的环境旋钮都是一个隐蔽的全局状态与潜在的降级分支,非必需的旋钮应当断然折叠为 显式常数。