# Evolution

> Bot team three-way mutual worker-optimization loop. Two evaluator bots design and dispatch test cases to a target bot via Firestore inbox, monitor real-time logs, compute metrics (fail_rate, empty_response_count, p50/p95 duration, avg_step_count), diagnose root causes, propose source-code fixes, then trigger cross-bot SIGHUP restart and re-test — all autonomously without asking Chris. Use when user says "进化"、"evolve"、"evolution round"、"进化一轮"、"start a round"、"互相 restart"、"三方互评"、"今晚优化 <bot>"、"组队优化" or asks the bot team to autonomously improve a specific worker (ClaudeCodeWorker / KiloWorker / OpenClawWorker / GeminiACPWorker).

- Skill: `yangwhale/evolution` (Agent Skill, multi-file: 13 files)
- Install (CLI): `npx skillmds@latest add yangwhale/evolution`
- Raw SKILL.md: https://api.skillmd.com/api/skills/yangwhale/evolution/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: yangwhale (https://skillmd.com/u/yangwhale)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/yangwhale/evolution

---


# Evolution — Bot Team Mutual Optimization

## Overview

每个 worker 都有自己看不见的盲区（流式协议、tool 注入、prompt 注入、空回复处理）——但从另一种 worker 的视角看，这些盲区是显眼的。Evolution skill 让 bunny（Claude Code）、小爱同学（Kilo）、铁幕（OpenClaw）三个 bot 互相当评估者，用对方的盲区作 case，跑 → 看 → 改 → 重启 → 再跑，直到指标改善。Chris 不参与每轮决策——授权已永久标记，bots 互相 restart 对方就行。

## When to Trigger

- Chris 说「进化」「今晚搞 evolution」「三方互评」「互相 restart」「组队优化 <bot>」
- 自己发现 worker 有明显问题（空回复率高 / step 不动 / 协议崩溃），且另一个 bot 在线
- 例行夜间任务（cron 配的话）

## Mode Selection（先决：同类 vs 跨类）

招募 evaluator 前先定模式，二者发现的 bug 类型完全不同：

| 模式 | 组成 | 擅长发现 | 盲区 | 触发场景 |
|---|---|---|---|---|
| **同类 (same-worker-type)** | 3 个 bot 都是同一 worker（比如全 ClaudeCodeWorker：jarvis + xiaoai + tiemu）| **Worker 内部实现 bug** — usage 字段失真、stream-JSON 拆分、状态机错误、prompt cache 行为、token 计算 | 大家盲区一致，跨协议接口看不到 | 怀疑某 worker 内部状态/计算/解析有问题；或想压测某 worker 的 stream/usage/cache pipeline |
| **跨类 (cross-worker-type)** | 3 个 bot 不同 worker（比如 claude + kilo + openclaw）| **协议层盲区** — IPC fast-path、MCP injection、control_request round-trip、permission 协议、空回复重试 | 单一 worker 内部细节抠不深 | 想发现接口契约不一致、新增 fast-path/control 类型后做 cross-worker 验证 |

**怎么选**:
- 想发现 worker 内部 bug → 同类（参考 2026-05-21 R5：3 个 ClaudeCodeWorker 锁定 `claude_code.py:824` usage 失真）
- 想发现协议盲区 → 跨类（参考 2026-05-19 R1-R6：claude/kilo/openclaw 三方发现 fast-path 系列问题）
- 默认推荐：先 1 轮跨类（接口盲区），再 1 轮同类（深挖 worker 实现）。两种都需要走下面同一套 12 步流程，只是 evaluator/target 招募范围不同

**同类模式特殊注意**:
- 因为 3 个 bot worker 一致, **同 bug 可能 3 个 bot 全都有**（不是 target 独占）。修复完必须 SIGHUP 全部 3 个 bot 才算完，不只 target
- 假设跨 bot 推广前必须 **raw jsonl grep 验证**（不要把 1 个 bot 看到的现象当成普适事实），参考 `feedback_usage-tracking-msg-id-dedupe` 里 xiaoai "CLAUDE.md 30K inject" 假设被 raw grep 证伪的案例

## The Round（12 步标准流程）

每轮一个 **target**（被优化的 bot），两个 **evaluators**（互相协作的另外两个 bot）。下面以 bunny+tiemu 优化 xiaoai 为例，角色可平移。

### 1. 选 target + 角色分配
- 看谁最近问题最多（Firestore `bots/{name}/logs` 翻 fail_rate）
- 两个 evaluator 在 #team-ops 频道商量并明确：「本轮 target=xiaoai (kilo)，evaluators=bunny+tiemu」
- 一句话发 Chris，FYI 不等审批

### 2. 招募 + 任务分工
- evaluator A 用 inbox 给 evaluator B 发：「我负责 case 1-3 (流式)、你负责 case 4-6 (MCP)、各自 dispatch」
- 不重复 case；如果对方静默 >10 min，evaluator A 单独 cover 全部 case

### 3. Dispatch cases
- 用 `scripts/dispatch-case.py` 把 case 通过 inbox 发到 target
- 每个 case 一条 inbox message，message 里写明：case_id / 输入 / 期望 / 评估维度（latency? completeness? tool_use?）
- 同时记下发送时间（用来后面 query logs）

### 4. 实时盯日志
- target bot 在自己机器上跑 case，bunny/tiemu 远程 query Firestore `bots/{target}/logs` 拉最新 N 条
- 也可以直接 `ssh <target_host> tail -f ~/.claude/closecrab/{target}/bot.log`
- 关键观察：worker 流式事件是否正常？tool_use 是否被 channel 看到？空回复触发了吗？

### 5. 算指标
- 用 `scripts/metrics-from-firestore.py --bot {target} --since <round_start>` 算：
  - `fail_rate` (status != "success")
  - `empty_response_count`
  - `duration_seconds` p50 / p95
  - `avg_step_count` per turn
  - `tool_call_diversity` (unique tools used)
- 输出 markdown 表给 Chris（dispatch 完一波就报一次，不憋大单）

### 6. 诊断
- 两个 evaluator 各自给出诊断（互不预告），写完后交叉看
- 如果两个诊断指向同一个根因 → 高信度，进入第 7 步
- 如果不一致 → 在 #team-ops 各自陈述，30 秒决出主诊断（按证据强度，不投票）

### 7. 提案修改
- evaluator A 写 patch（修 target 的 worker 源码 / SKILL.md / 配置）
- patch 必须 grep 验证过相关代码确实存在（参考 `feedback_grep-source-before-asserting-architecture`）
- 不 patch target 本身的 memory 或 instructions，避免 target 「学到」当前 case 的答案而非泛化

### 8. 推送 patch + 远程 pull
- evaluator 在本地 git commit + push（CloseCrab repo）
- ssh 到 target 机器 `cd ~/CloseCrab && git pull`

### 9. 跨 bot SIGHUP restart
- `bash scripts/restart-peer-bot.sh <target>`
- 这个脚本用「12s/8s nohup + sleep + kill -HUP」pattern（见 `references/cross-bot-restart-protocol.md`）
- 必须验证旧 PID 消失 + 新 PID 出现 + bot.log 有 18:10:19 / Phase E xxxx chars 的启动行

### 10. Re-test 同一组 case
- 用 `scripts/dispatch-case.py --rerun <round_id>` 把 step 3 的同一批 case 再发一遍
- 不改 case 内容，纯粹看 patch 是否解决问题

### 11. 对比指标
- 再跑一次 step 5，diff 两轮：「fail_rate 30%→5%」「empty_response 8 → 0」「p95 12s → 4s」
- 没改善或更糟 → 回到 step 7，patch 重写（最多 3 次循环，避免抽搐）

### 12. Round report + GBrain 落地
- evaluator A 写 round report（target / cases / metrics before-after / patch / lesson）到 GBrain（`put_page` slug=`round_<date>_<target>`）
- 把可复用的 lesson 也写到 feedback page（`feedback_xxx`）
- 在 #team-ops 一句话 summary，@Chris FYI

## R4-style Free Exploration（探索"未知未知" bug）

12 步标准流程要 evaluator 提前写好 case 派给 target，前提是「我们已经知道要测什么」——擅长验证假设，但发现新 bug 受限于评估者想象力。R4 free-exploration 模式补足这块：让 bot 自挑探查维度。

### 适用场景
- worker 跑了一段时间稳定 → 找不出明显 case 但怀疑还有隐藏 bug
- 长上下文 / 新模型上线后做"基线扫描"，找一切异常
- standard 流程 N 轮收敛后想换视角（参考 2026-05-21 R4：tiemu 选「Firestore usage 字段 0 token 异常」维度，锁定 `claude_code.py:824` 失真根因，此前 R1-R3 standard case 完全没暴露）

### 跟标准 12 步的差异
| 阶段 | Standard | Free Exploration |
|---|---|---|
| 招募 | evaluator 派 case | target 自挑维度 |
| Dispatch 内容 | 具体 case + 期望 | 给 N 个候选探查维度 + 「选 1-2 个深挖」 |
| 评估指标 | 跟 case 设计一致 | 由 target 在 done 报告里自陈"我看到什么" |
| 修复 | evaluator 写 patch | target 提 patch 提案，evaluator 复核 |

### Dispatch 模板（给 target 用 inbox V1 协议）
```
evo-r{N} free-exploration

请你自己挑 1-2 个维度深挖，找出能复现的 worker bug。候选维度：
(a) stream-JSON 解析路径 — assistant event 拆分 / tool_use 边界
(b) usage 字段语义 — input/output/cache_create/cache_read 统计是否准
(c) control_request round-trip — ExitPlanMode / AskUserQuestion fast-path
(d) cache 行为 — fresh restart 后第一个 turn / autocompact 边界
(e) Firestore log finalize — usage / steps / status 是否对齐
(f) 你自己想到的其他维度

要求：done 报告里列「选了哪个维度 / 看了什么 / 锁定的根因 / patch 提案」。
预算：30 分钟内闭环；不要展开成长项目。
```

### Anti-pattern
- **不要把 free-exploration 当 case dispatch 用**：明确探查范围，但不要预设答案。如果你已经知道要找什么，走标准 12 步更高效
- **target 自己提的 patch 必须 evaluator 复核**：避免自查自纠盲区，参考 [[feedback-evolution-r3-prompt-fix-vs-tool-impl]] 关于改 prompt vs 改源码的判断

## Authorization Scope（永久授权）

Chris 已经永久授权 evolution 流程内的以下动作，不需要每轮再问：

| Action | 是否需要问 | Owner |
|---|---|---|
| 跨 bot SIGHUP restart 对方 (evolution round 内) | 否 | 任何 evaluator |
| 给对方 bot 的源码提 patch + push + 远程 pull | 否 | 任何 evaluator |
| 修 target 的 SKILL.md / GBrain page | 否 | 任何 evaluator |
| dispatch case 到任意 bot 的 inbox | 否 | 任何 evaluator |
| 上面以外的破坏性动作（删数据 / 改密钥 / 改 channel 配置） | **是** | Chris |

授权依据：Chris 原话「你就互相 restart 呗，不要让我参与。然后你把这个能力做成一个 skill，就叫做进化」（2026-05-19）。

## Resources

### scripts/
- `restart-peer-bot.sh <bot_name>` — 跨 bot SIGHUP restart（12s nohup pattern，含 PID 验证）
- `dispatch-case.py --target <bot> --case <id> --content "..."` — Firestore inbox dispatch wrapper
- `metrics-from-firestore.py --bot <name> --since <ISO>` — 算 fail_rate / empty_response_count / p50p95 duration / avg_step_count

### 共享 scripts/（Round 3-6 沉淀 — 在 `~/CloseCrab/scripts/`）
- `test-fast-path.py <bot> <Tool>` — grep bot.log 取四元组（control_request_time / response_time / gap_ms / exact_return_string），自动判 fast-path PASS/FAIL。Anti-pattern 2 防御。
- `check-binary-alignment.py <bot> [--commit SHA]` — `ps lstart` vs git commit 时间，bot 落后则 FAIL 并打印 SIGHUP 重启命令。Anti-pattern 1 防御。
- `test-cross-worker-invariant.py <return_string> [...]` — 一条命令 grep 4 worker 的 control_response 解析逻辑（claude_code 用 AST 解 `_approve_keywords`），验证 fast-path 返回值是否被所有 downstream worker 识别。Anti-pattern 3 防御。
- `test-multi-q-routing.py [--json]` — **Round 6 新增**：mock unit test 验证 claude_code + kilo 的 AskUserQuestion 多问路由（per-Q 1:1 / broadcast / single-Q 三 case）。Anti-pattern 4 防御。**修改 multi-input fast-path 后必跑一次**，零中断风险（不需要 SIGHUP，不 dispatch live case）。

Round 3+ 跑 case 之前一行命令组合验证:
```bash
# 一条命令完成 R3+R6 四 anti-pattern 自检
python3 ~/CloseCrab/scripts/check-binary-alignment.py bunny && \
  python3 ~/CloseCrab/scripts/test-cross-worker-invariant.py approved && \
  python3 ~/CloseCrab/scripts/test-multi-q-routing.py && \
  echo "✅ binary aligned + invariant OK + multi-Q routing OK, 可以 dispatch case"
# case 跑完
python3 ~/CloseCrab/scripts/test-fast-path.py bunny ExitPlanMode
```

### 静态自审模式（Round 6 新增）

跨 worker 同根 bug 检测（无需 dispatch + restart, 单 turn 闭环）:

1. R4/R5 在 worker X 发现 bug 后, **第一时间** grep 其他 worker 同 pattern (`_build_control_response` / `on_input_needed` / `on_question_asked`)
2. 写 mock unit test 用 `Worker.__new__()` 绕过 subprocess 启动, 直接调目标函数
3. 验证 3 cases (per-input 1:1 / broadcast / 单 input 退化) 全 PASS 再 commit
4. 适用场景: target = self (evaluator + target 同进程, SIGHUP 会中断 user-facing session) 或 cross-worker pattern match 但 dispatch 成本高

### references/
- `cross-bot-restart-protocol.md` — SIGHUP 协议详解、12s nohup 为什么 work、PID 验证清单、failure modes
- `silent-failure-detection.md` — **Round 2 新增**：messages.status / logs.status / bot.log 三源对齐，避免 Round 1 那种"5 done + 1 silent fail 当成 6 done"的报告失真
- `control-request-fastpath.md` — **Round 2 新增**：inbox 派活时 ExitPlanMode/AskUserQuestion 必须走 fast-path，避免 5min × N 累积命中 BotCore lock timeout
- `case-design-checklist.md` — **Round 3+4 沉淀**：case 设计/执行 8 问自查清单 + 4 个 anti-pattern（stale binary / 只看下游不取四元组 / fast-path return 跨层 contract 不 round-trip / multi-input cross-worker callback contract gap）。任何 fast-path / control-request / IPC 类 case 都要过这关
- `cross-worker-capability-matrix.md` — **Round 5 沉淀**：claude/kilo/openclaw/gemini 在 control_request / fast-path / permission 路径上的能力矩阵。**case 设计前必查此表**，否则可能像 R5 case 1 一样基于错误假设浪费一轮 dispatch。
- `anomaly-metrics.md` — **2026-05-21 R5 新增**：`metrics-from-firestore.py` 自动检测的 3 个已知 bug 签名（out_tokens=1 多步 / all-zero usage / large cache_create）+ 怎么诊断 + 跨 worker 适用性。step 5 算指标时自动 flag，发现非零先排查再 dispatch fix
- `mock-test-template/` — fast-path callback + round-trip 测试模板，含 negative test 防 approval bypass
- `case-library/kilo-cases.md` — Kilo (xiaoai) 已知盲区 + cases
- `case-library/openclaw-cases.md` — OpenClaw (tiemu) 已知盲区 + cases（待写）
- `case-library/claude-cases.md` — Claude Code (bunny) 已知盲区 + cases（待写）

## Workflow Examples

### 例 1：「进化一轮 xiaoai」
1. Chris 说「进化一轮 xiaoai」
2. bunny 先 `inbox-send.py tiemu "evolution round target=xiaoai, 我负责流式 case 1-3, 你负责 MCP case 4-6"`
3. bunny dispatch case 1-3 → 等 5 min → 算 metrics → 诊断 → 写 patch → push
4. ssh xiaoai-host && git pull
5. `bash restart-peer-bot.sh xiaoai`
6. dispatch case 1-3 再跑一次
7. diff metrics → 写 round report

### 例 2：「三个 bot 互相进化一轮，把今晚的精华时间用完」
1. Round 1: bunny + tiemu 优化 xiaoai
2. Round 2: xiaoai + bunny 优化 tiemu
3. Round 3: xiaoai + tiemu 优化 bunny
- 每轮独立写 round report
- 一轮结束才进下一轮（不并发，避免互相 restart 时打到对方还在跑的进程）

## Anti-Patterns（不要做）

- ❌ **不要假设 worker_type**：每次先 query Firestore `bots/{name}.worker_type` 拿真值（参考 `feedback_grep-source-before-asserting-architecture`）
- ❌ **不要 patch target 的 instructions/memory 让它学会答 case**：这是过拟合，要 patch worker 源码让能力泛化
- ❌ **不要不验证 restart 就 re-test**：必须确认新 PID + bot.log startup 行，否则你 re-test 的还是老进程
- ❌ **不要 round 内联系 Chris 等他批 patch**：授权范围内自己跑，round 结束才一句话 FYI
- ❌ **不要 round 跨夜还在 loop**：每个 target 一轮内最多 3 次 patch 循环，无改善就写"本轮失败、root cause 待人工"封轮
- ❌ **不要 SIGKILL target**：用 SIGHUP，让 run.sh wrapper 干净重启，避免丢 session 状态
- ❌ **不要只看 `messages.status` 当 case outcome**（Round 2 教训）：messages 表的 status 是 inbox envelope 的默认值，**真实结果在 `bots/{target}/logs`**。silent failure 形态：messages.status=done 但 logs 表无对应 turn。**Round report 必须 messages × logs × bot.log 三源对齐**。详见 `references/silent-failure-detection.md`
- ❌ **不要让 worker 的 ExitPlanMode / AskUserQuestion 走 user-facing callback 处理 inbox 派活**（Round 2 教训）：没有真用户能答 → 5min 超时 × N 次 control_request → 命中 BotCore 1800s lock timeout → 强杀级联。channel 的 `_make_input_callback` 必须有 `is_inbox` fast-path（详见 `references/control-request-fastpath.md`）
- ❌ **不要不验证 bot binary alignment 就跑 fast-path test**（Round 3 教训）：bot lstart < commit time → 跑的是旧版本，下游行为偶尔"正确"是巧合。case 第一行必须 `ps -eo lstart` vs `git log` 对齐。详见 `references/case-design-checklist.md` anti-pattern 1
- ❌ **不要只看下游行为就报 PASS**（Round 3 教训）：必须取 source-of-truth 四元组（control_request_time / control_response_time / gap_ms / exact_return_string）。gap_ms < 100ms 才是真 fast-path，否则可能是 user 手点 card / 5min 超时返回 "继续" 误打误撞。详见 `references/case-design-checklist.md` anti-pattern 2
- ❌ **不要 patch fast-path return 值前不 grep 所有 worker downstream consumer**（Round 3 教训）：fast-path 是 channel↔worker 跨层 contract，channel 返回 "approved" 但 worker `_approve_keywords` 没这个词 → behavior=deny。patch PR 必须附带 cross-worker grep 矩阵（4 worker × N 返回字符串）+ negative round-trip test。详见 `references/case-design-checklist.md` anti-pattern 3
- ❌ **不要不分 prompt-fix vs tool-impl 边界就提改进**（R3 教训）：改 LLM 行为前先判根因 — LLM 决策 (Read limit / wc 前置 / 不切 model) 改 prompt 就行；tool 实现 (Grep 没暴露 --follow / 内部状态 bug) 必须改 worker/binary 源码。误把 tool-impl 当 prompt-fix 写一堆 rule，LLM 看了也救不了。详见 [[feedback-evolution-r3-prompt-fix-vs-tool-impl]]
- ❌ **不要把 1 个 bot 的现象当成普适事实推广**（R5 教训）：R5 xiaoai 假设「CLAUDE.md 每 turn inject 30K」听起来合理，但 grep raw jsonl `Contents of /home` = 0 matches，真根因是 assistant `thinking` block。**跨 bot 推广前必须 raw jsonl grep / Firestore 字段实查**，不要靠 bot 自报的解释直接信。详见 [[feedback-usage-tracking-msg-id-dedupe]]

## Failure Modes & Recovery

| Symptom | Likely Cause | Fix |
|---|---|---|
| restart 后新 PID 没出现 | run.sh wrapper 死了 | ssh 上去 `./run.sh <bot> &` 手动起，并查 nohup.out |
| dispatch 后 inbox status 一直 pending | target 进程死了 / inbox watcher 异常 | step 1：ps aux \| grep <bot>；step 2：tail bot.log 找 watcher 异常 |
| metrics 拉不到 (Firestore 查询报 grpc) | query 太复杂或权限不对 | 简化 query（只按 timestamp 过滤），用 `gcloud auth application-default login` 重新认证 |
| 两个 evaluator 诊断打架不收敛 | case 设计模糊 | 重新设计 case 让信号锐利（一次只测一个维度） |
| patch push 后 target 拉不到 | 远程仓库未同步 / 网络 | ssh target && cd CloseCrab && git fetch origin && git log -1 origin/main 确认 |

## See Also

- GBrain page: `feedback_strong-leads-weak-evolution` — 第一轮强带弱的策略说明
- GBrain page: `chris-authorized-cross-bot-restart` — Chris 授权全文
- `~/CloseCrab/CLAUDE.md` 的「Bot Team 系统」段

