diff --git a/README.md b/README.md
index d271571..6d3fee5 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,12 @@
# Evolution Kernel
- Give an LLM a goal. Watch your repo improve itself. Stop when the budget runs out.
+ Give an LLM a goal. Watch your codebase improve itself. Stop when the budget runs out.
- A ~1,200-line Python runtime for autonomous, multi-round code improvement — sandboxed, audited, and fully reversible.
+ A ~1,200-line Python runtime that runs an autonomous, multi-round improvement loop on any codebase —
+ sandboxed in git worktrees, every decision logged, every change reversible.
@@ -19,52 +20,58 @@
-
-
-
+
+
+
+
+
+---
+
+
+ Think of it as AlphaEvolve — but pointed at your own repository.
+ You define what "better" means. The kernel figures out how to get there.
---
## What it does
-Write a YAML file that says what "better" means. Evolution Kernel runs a tight loop:
+Point Evolution Kernel at any git repository and give it a measurable goal. It runs a closed loop:
-1. **Observe** — collect the current metric (coverage %, benchmark score, lint count — whatever your shell command outputs)
-2. **Plan** — an LLM reads the metric and the history of prior attempts, then writes a concrete plan
-3. **Execute** — a coding agent (Aider or Claude Code) applies the plan inside a git worktree sandbox
-4. **Evaluate** — the evaluator re-runs your metric command and decides accept or reject
-5. **Commit or roll back** — accepted changes become a real git commit; rejected ones are discarded
-6. **Loop** — repeat until a budget limit fires (`max_iterations`, `max_total_usd`, `max_total_tokens`)
+| Step | What happens |
+|:---:|---|
+| 🔍 **Observe** | Run your metric command — collect the current state (win rate, latency, error count, …) |
+| 🧠 **Plan** | LLM reads the metric + history of prior attempts, produces a concrete plan |
+| 🔨 **Execute** | Coding agent (Aider or Claude Code) applies the plan inside an isolated git worktree |
+| ⚖️ **Evaluate** | Re-run your metric; LLM decides accept or reject |
+| ✅ **Commit / rollback** | Accepted → real git commit on `evolution/accepted`. Rejected → worktree discarded |
+| 🔁 **Loop** | Repeat until `max_iterations`, `max_total_usd`, or `max_total_tokens` fires |
-Every attempt — accepted or rejected — is written to a structured **ledger** so you can audit exactly what the LLM tried, what changed, and why each round was accepted or rejected.
+Every attempt is written to a **ledger**: goal, observation, plan, diff, evaluation, decision. Nothing is held in memory. An external auditor — or your future self — can reconstruct every decision from the ledger alone.
---
## Quick Start
```bash
-# 1. Install (single runtime dependency: PyYAML)
+# 1. Install
pip install evolution-kernel
-# 2. Write a goal config
+# 2. Describe your goal
cat > evolution.yml << 'EOF'
-mission: "Increase src/ test coverage from 40% to 80%"
+mission: "Evolve the game AI to win at least 60% of games against the built-in opponent"
evidence_sources:
- type: shell
- command: >
- python3 -m pytest --cov=src --cov-report=json -q &&
- python3 -c "import json; d=json.load(open('coverage.json'));
- print(f'coverage: {d[\"totals\"][\"percent_covered\"]:.1f}%')"
+ command: "python3 scripts/tournament.py --games 20 --json"
mutation_scope:
- allowed_paths: ["tests/"]
+ allowed_paths: ["ai/"]
hard_stops:
- max_iterations: 20
- max_consecutive_failures: 3
- max_total_usd: 2.00
+ max_iterations: 30
+ max_consecutive_failures: 4
+ max_total_usd: 3.00
llm:
provider: anthropic
@@ -80,75 +87,88 @@ roles:
evaluator: ["python3", "roles/evaluator.py"]
EOF
-# 3. Run until the budget fires
-evolution-kernel --config evolution.yml --repo /path/to/your-project --ledger /tmp/ledger --loop
+# 3. Run — walk away
+evolution-kernel --config evolution.yml --repo /path/to/game --ledger /tmp/ledger --loop
```
---
-## Example: raising test coverage from 40% to 80%
+## See it in action
+
+### Evolving a game AI from 35% to 72% win rate — overnight, unattended
-The loop emits one JSON object per round. A realistic session looks like this:
+```
+before ███░░░░░░░░░ 35% win rate (loses 13 of 20 games)
+after ███████░░░░░ 72% win rate (wins 14 of 20 games)
+9 rounds · $2.14 · 0 minutes of your time
```
-Round 1 observe: coverage 40.2%
- plan → "Add unit tests for src/parser.py — parse_tokens is completely uncovered"
- execute → aider writes tests/test_parser.py (14 new assertions)
- eval → coverage 51.7% — ACCEPT
- commit → a3f1c9e "tests: cover parse_tokens (coverage 40→52%)"
-
-Round 2 observe: coverage 51.7%
- plan → "Add edge-case tests for src/validator.py, missing branch coverage on error paths"
- execute → aider extends tests/test_validator.py (+9 tests)
- eval → coverage 63.4% — ACCEPT
- commit → 8b2de01 "tests: validator edge cases (coverage 52→63%)"
-
-Round 3 observe: coverage 63.4%
- plan → "Cover src/formatter.py — currently 0% covered"
- execute → aider writes tests/test_formatter.py
- eval → coverage 63.4% — new test file has wrong import path — REJECT
- rollback → worktree discarded, main branch unchanged (consecutive_failures: 1)
-
-Round 4 observe: coverage 63.4%
- plan → "tests/test_formatter.py failed due to import error; fix path and retry"
- execute → aider fixes import in tests/test_formatter.py
- eval → coverage 74.8% — ACCEPT
- commit → 2c9af44 "tests: formatter coverage, fixed import (coverage 63→75%)"
+
+Here is what the loop actually does, round by round:
+
+```
+Round 1 observe: win_rate 35%
+ plan → "Greedy score maximization with no lookahead — add 2-ply minimax"
+ execute → aider rewrites ai/strategy.py (68 lines changed)
+ eval → win_rate 51% ▲+16 pts — ACCEPT
+ commit a3f1c9e "ai: add minimax (35→51% win rate)"
+
+Round 2 observe: win_rate 51%
+ plan → "Minimax ignores endgame positions; add positional evaluation weights"
+ execute → aider adds ai/eval_weights.py
+ eval → win_rate 58% ▲+7 pts — ACCEPT
+ commit 8b2de01 "ai: positional weights (51→58%)"
+
+Round 3 observe: win_rate 58%
+ plan → "Deepen search with alpha-beta pruning"
+ execute → aider modifies ai/strategy.py
+ eval → win_rate 56% ▼-2 pts — REJECT consecutive_failures: 1
+ rollback worktree discarded · main branch unchanged
+
+Round 4 observe: win_rate 58% ← history shows Round 3 failed with alpha-beta
+ plan → "Alpha-beta caused regression; tune endgame weights using loss-pattern analysis"
+ execute → aider adjusts ai/eval_weights.py
+ eval → win_rate 67% ▲+9 pts — ACCEPT
+ commit 2c9af44 "ai: endgame weight tuning (58→67%)"
...
-Round 12 observe: coverage 80.1%
- eval → coverage 80.1% — threshold reached — ACCEPT
- commit → 9d7b321 "tests: final push past 80% target"
+Round 9 observe: win_rate 72%
+ eval → 72% — target 60% exceeded — ACCEPT
+ commit 9d7b321 "ai: final tuning pass (70→72%)"
-{"halted": true, "reason": "max_iterations reached", "iterations": 20, "total_usd": 1.43, "total_tokens": 487201}
+{"halted": true, "reason": "max_iterations reached", "iterations": 30, "total_usd": 2.14, "total_tokens": 634000}
```
-Each accepted change is a reversible git commit on the `evolution/accepted` branch. The LLM self-corrected on Round 4 using the rejection history from Round 3 — this is what history injection does.
+> **Round 3 is the key moment.** Alpha-beta pruning made things *worse*, so the system rejected the change and left the codebase untouched. Round 4 shows the LLM reading the rejection history and changing its approach. This is what "memory" means in practice — not guessing the same wrong answer twice.
---
-## Ledger structure
-
-Every round writes a full evidence trail. Nothing is stored in memory; an external auditor can reconstruct every decision from the ledger directory alone.
+## Ledger: the complete audit trail
```
ledger/
- .evolution_state.json # persisted counters (iterations, usd, tokens) — survives restarts
+ .evolution_state.json ← budget counters; survives restarts
runs/
0001/
- config.json # full snapshot of your evolution.yml
- observation.json # raw output of your evidence_sources commands
- plan.json # LLM plan: summary, steps, expected_improvement
- patch.diff # exact diff the executor applied
- candidate_commit.txt # git SHA of the sandbox commit
- evaluation.json # verdict + metrics + cost_usd + tokens_used
- decision.json # accept / reject + reason
- reflection.json # one-line summary injected into the next round's history
- 0002/
- ...
+ config.json ← full snapshot of your evolution.yml
+ observation.json ← raw output of your evidence_sources commands
+ plan.json ← LLM plan: summary · steps · expected_improvement
+ patch.diff ← exact diff the executor applied
+ candidate_commit.txt ← git SHA of the sandbox commit
+ evaluation.json ← verdict + metrics + cost_usd + tokens_used
+ decision.json ← accept / reject + reason
+ reflection.json ← one-line summary injected into the next round
+ 0002/ ...
halted/
- 20260501T120000Z.json # written when any hard stop fires
+ 20260501T120000Z.json ← written when any hard stop fires
+```
+
+To undo every change from a session:
+
+```bash
+git checkout evolution/accepted
+git reset --hard # every accepted change is a named commit
```
---
@@ -159,40 +179,40 @@ ledger/
flowchart LR
Config[evolution.yml] --> Governor
- subgraph loop ["Loop until hard stop"]
+ subgraph loop ["↻ Loop until hard stop fires"]
direction LR
- Governor -->|"planner_input.json\n(goal + observation + history)"| Planner["Planner\nLLM"]
- Planner -->|plan.json| Executor["Executor\nAider / Claude Code"]
- Executor -->|patch in git worktree| Evaluator["Evaluator\nLLM + shell"]
+ Governor -->|"planner_input.json\ngoal · observation · history"| Planner["🧠 Planner\nLLM"]
+ Planner -->|plan.json| Executor["🔨 Executor\nAider / Claude Code"]
+ Executor -->|patch in git worktree| Evaluator["⚖️ Evaluator\nLLM + shell"]
Evaluator -->|evaluation.json| Governor
end
- Governor -->|"accept → git commit"| AcceptedBranch[evolution/accepted]
- Governor -->|"reject → discard worktree"| Ledger[Ledger]
+ Governor -->|"accept → git commit"| Branch["evolution/accepted"]
+ Governor -->|"reject → discard"| Ledger[📁 Ledger]
Governor --> Ledger
```
-**The Governor is intentionally dumb.** It is pure orchestration — no LLM calls of its own. All intelligence lives in the three role scripts. You can swap any role for your own implementation; the Governor only cares about the JSON files roles read and write.
+**The Governor is intentionally dumb.** It is pure orchestration — zero LLM calls. All intelligence lives in the three role scripts. Swap any role for your own implementation; the Governor only cares about the JSON each role reads and writes.
-**Roles communicate through files, not shared memory.** The planner never talks directly to the executor. The evaluator never sees the executor's self-assessment. The only shared state is the ledger.
+**Roles communicate through files, not shared memory.** The planner never talks to the executor. The evaluator never sees the executor's self-assessment. The only shared state is the ledger.
---
-## Capabilities
+## What works today
| Feature | Status |
-|---|---|
-| Multi-round LLM loop with memory (history injection) | ✅ Working |
-| Budget guards: `max_total_usd`, `max_total_tokens` | ✅ Working |
-| Iteration / consecutive-failure hard stops | ✅ Working |
-| Full ledger audit trail (survives process restarts) | ✅ Working |
-| Git worktree sandbox — every attempt isolated | ✅ Working |
-| Scope enforcement — rejects changes outside `allowed_paths` | ✅ Working |
-| Config-driven: swap LLM provider, model, coding agent | ✅ Working |
-| Aider and Claude Code executor support | ✅ Working |
-| Anthropic and OpenAI planner/evaluator support | ✅ Working |
+|---|:---:|
+| Multi-round LLM loop with memory (history injection) | ✅ |
+| Budget guards: `max_total_usd`, `max_total_tokens` | ✅ |
+| Iteration / consecutive-failure hard stops | ✅ |
+| Full ledger audit trail (survives process restarts) | ✅ |
+| Git worktree sandbox — every attempt isolated | ✅ |
+| Scope enforcement — rejects changes outside `allowed_paths` | ✅ |
+| Config-driven: swap LLM provider, model, coding agent | ✅ |
+| Aider and Claude Code executor support | ✅ |
+| Anthropic and OpenAI planner/evaluator support | ✅ |
| Goal evaluator — stops when mission is "won" | 🔧 PR #5 |
-| k-branch parallel exploration (FunSearch style) | 🔧 PR #6 |
+| k-branch parallel exploration (FunSearch / AlphaEvolve style) | 🔧 PR #6 |
| Process sandbox (firejail / bwrap) for production safety | 🔧 PR #7 |
---
@@ -200,43 +220,42 @@ flowchart LR
## Configuration reference
```yaml
-# Required — free-text statement of what "better" means
-mission: "Increase src/ test coverage from 40% to 80%"
+# Required — what "better" means for your project
+mission: "Evolve the game AI to win at least 60% of games"
-# How to measure the current state of the target repo
+# How to measure the current state
evidence_sources:
- - type: shell # runs a command; stdout goes into observation.json
- command: "python3 -m pytest --cov=src -q && ..."
- - type: file # reads a file; content goes into observation.json
+ - type: shell # stdout goes into observation.json
+ command: "python3 scripts/tournament.py --games 20 --json"
+ - type: file # file contents go into observation.json
path: "metrics.json"
-# Only files under these paths may be modified by the executor
+# Only files under these paths may be changed
mutation_scope:
allowed_paths:
- - "tests/" # changes outside this list are auto-rejected
+ - "ai/" # changes outside this list are auto-rejected
# When to stop
hard_stops:
- max_iterations: 10 # total rounds (required, must be ≥ 1)
- max_consecutive_failures: 3 # consecutive rejections before halt (required)
- max_total_usd: 0.0 # 0 = unlimited
+ max_iterations: 30 # total rounds
+ max_consecutive_failures: 4 # consecutive rejections before halt
+ max_total_usd: 3.00 # 0 = unlimited
max_total_tokens: 0 # 0 = unlimited
-# LLM used by the planner and evaluator role scripts
+# LLM for planner and evaluator
llm:
provider: anthropic # anthropic | openai
model: claude-sonnet-4-6
api_key_env: ANTHROPIC_API_KEY
-# Coding agent used by the executor role script
+# Coding agent for executor
coding_agent:
tool: aider # aider | claude-code
-# How many past rounds the planner sees as context
+# How many past rounds the planner sees
history:
max_entries: 10
-# The three role commands (each receives --input, --output, --worktree)
roles:
planner: ["python3", "roles/planner.py"]
executor: ["bash", "roles/executor.sh"]
@@ -244,7 +263,6 @@ roles:
```
**Switch to OpenAI:**
-
```yaml
llm:
provider: openai
@@ -252,8 +270,7 @@ llm:
api_key_env: OPENAI_API_KEY
```
-**Switch to Claude Code as coding agent:**
-
+**Switch to Claude Code:**
```yaml
coding_agent:
tool: claude-code
@@ -261,20 +278,20 @@ coding_agent:
---
-## CLI reference
+## CLI
```bash
-# Run the multi-round loop (recommended — stops when a hard stop fires)
+# Loop until a hard stop fires (recommended)
evolution-kernel --config evolution.yml --repo /path/to/repo --ledger /tmp/ledger --loop
-# Run exactly one round
+# Single round
evolution-kernel --config evolution.yml --repo /path/to/repo --ledger /tmp/ledger
-# Reset hard-stop counters to start a fresh session
+# Reset budget counters after a halt
evolution-kernel --ledger /tmp/ledger --reset
```
-Exit codes: `0` = clean finish, `3` = halted by a hard stop.
+Exit codes: `0` clean finish · `3` halted by a hard stop.
---
@@ -284,7 +301,7 @@ Exit codes: `0` = clean finish, `3` = halted by a hard stop.
pip install evolution-kernel
```
-From source (the only runtime dependency is PyYAML):
+From source (only runtime dependency: PyYAML):
```bash
git clone https://github.com/Protocol-zero-0/evolution-kernel.git
@@ -292,60 +309,46 @@ cd evolution-kernel
pip install -e .
```
-Python 3.10 or later required.
+Python 3.10 or later.
---
-## Running the tests
+## Tests
```bash
python3 -m pytest tests/ -v
```
-All tests run locally with no network calls — roles are replaced by lightweight fixture scripts.
+39 tests · no network calls · roles replaced by lightweight fixture scripts.
---
-## Writing your own role scripts
+## Writing your own roles
-Each role is an executable that receives three arguments:
+Each role is an executable that receives:
-```text
---input JSON the governor prepared for this role
---output JSON the role must write before exiting
---worktree path to the isolated git sandbox checkout
```
-
-The built-in `roles/planner.py`, `roles/executor.sh`, and `roles/evaluator.py` are the reference implementation. Copy and modify them, or replace them entirely with a shell script, a Python program, or a Docker call. The Governor has no opinion on what runs inside a role.
-
----
-
-## Rollback
-
-Every accepted change is a commit on the `evolution/accepted` branch. To undo everything from a session:
-
-```bash
-git checkout evolution/accepted
-git log --oneline # find the baseline commit before the session
-git reset --hard # roll back all accepted changes
+--input JSON the governor wrote for this role
+--output JSON the role must write before exiting
+--worktree path to the isolated git sandbox checkout
```
-Rejected experiments are never promoted, so only the changes your evaluator explicitly accepted survive.
+`roles/planner.py`, `roles/executor.sh`, and `roles/evaluator.py` are the reference implementation. Copy, modify, or replace them entirely — with a shell script, a Docker call, or anything that reads `--input` and writes `--output`.
---
## Project layout
```
-evolution_kernel/ # ~1,200-line runtime (Governor, Observer, HardStops, Config, CLI)
-roles/ # reference planner, executor, and evaluator implementations
-examples/ # demo target + evolution.yml to run out of the box
-docs/ # protocol spec
-tests/ # unit + acceptance tests (39 tests, no network required)
+evolution_kernel/ ~1,200-line runtime (Governor · Observer · HardStops · Config · CLI)
+roles/ reference planner, executor, evaluator
+examples/ demo target + working evolution.yml
+docs/ protocol spec
+tests/ 39 unit + acceptance tests
```
---
## License
-MIT. See [LICENSE](LICENSE).
+MIT — see [LICENSE](LICENSE).
diff --git a/README.zh.md b/README.zh.md
index 113b5bf..72cd391 100644
--- a/README.zh.md
+++ b/README.zh.md
@@ -1,241 +1,354 @@
# Evolution Kernel
- 一个用于自主优化软件项目的通用进化引擎。
+ 给 LLM 一个目标,让代码库自己进化,预算用完自动停。
+
+
+
+ 约 1,200 行 Python 运行时,对任意代码库跑全自动多轮改进循环——
+ 隔离在 git worktree 沙箱里,每一个决策留档,每一次变更可回滚。
English
·
- 协议
- ·
- 首个优化对象
+ 协议文档
-
-
-
-
-
+
+
+
+
+
+
+
-**Evolution Kernel** 是一个面向“自主自我进化软件系统”的最小协议与运行时。
+---
-它不是某个具体项目的自动化脚本,而是一个通用的进化内核。它的目标是让软件项目的持续改进过程变得**可控、可复现、可沙箱化、可审计、可回滚**。只要一个项目能够提供目标、沙箱和评估器,就可以成为它的优化对象。
+
+ 把它理解成 AlphaEvolve——但目标是你自己的代码仓库。
+ 你定义"更好"是什么意思,内核负责找到如何到达那里。
+
-## 为什么需要它
+---
-现代 coding agent 可以提出并修改代码,但长期的软件自我改进不只需要代码生成,还需要一个稳定的内核来管理整个进化闭环:
+## 它做什么
-- 定义目标项目里的“改进”到底意味着什么;
-- 在影响已接受分支之前隔离每一次实验;
-- 用可复现的标准评估候选变更;
-- 只晋升通过评估的候选结果;
-- 记录每次实验发生了什么、为什么接受或拒绝。
+把 Evolution Kernel 指向任意 git 仓库,给它一个可衡量的目标,它就跑起一个闭环:
-Evolution Kernel 将这个闭环做成一个小而可检查的运行时。
+| 步骤 | 发生了什么 |
+|:---:|---|
+| 🔍 **观察** | 运行你的指标命令——采集当前状态(胜率、延迟、报错数……) |
+| 🧠 **规划** | LLM 读取指标 + 历史轮次记录,生成一个具体的改进方案 |
+| 🔨 **执行** | Coding agent(Aider 或 Claude Code)在隔离的 git worktree 里实施方案 |
+| ⚖️ **评估** | 重新运行指标;LLM 判断接受还是拒绝 |
+| ✅ **提交 / 回滚** | 接受 → 在 `evolution/accepted` 上留下真实的 git commit。拒绝 → worktree 直接丢弃 |
+| 🔁 **循环** | 重复,直到 `max_iterations`、`max_total_usd` 或 `max_total_tokens` 触发 |
-## 进化闭环
+每一次尝试都写入 **ledger**:目标、观察、方案、diff、评估、决策。不依赖内存。任何外部审计者——或未来的你——都能从 ledger 单独复盘每一个决定。
-```mermaid
-flowchart LR
- Goal[Goal] --> Governor[Governor]
- Governor --> Planner[Planner]
- Planner --> Plan[plan.json]
- Plan --> Executor[Executor]
- Executor --> Candidate[Sandbox candidate]
- Candidate --> Evaluator[Evaluator]
- Evaluator --> Eval[evaluation.json]
- Eval --> Governor
- Governor --> Accepted[evolution/accepted]
- Governor --> Ledger[Ledger]
-```
+---
-## 首个优化对象
+## 快速上手
-Evolution Kernel 的定位是优化**任何**软件项目。它第一个正在优化的项目是 **Token-Ignition**,具体对象是 Token-Ignition 的后端评估器。
+```bash
+# 1. 安装
+pip install evolution-kernel
-因此,Token-Ignition 是第一个优化对象和参考适配器,不是 Evolution Kernel 的硬依赖。它用来验证这个内核能否安全、确定性地进化一个真实代码库,同时保持运行时足够小。
+# 2. 描述你的目标
+cat > evolution.yml << 'EOF'
+mission: "让游戏 AI 对内置对手的胜率达到 60% 以上"
-## 当前状态
+evidence_sources:
+ - type: shell
+ command: "python3 scripts/tournament.py --games 20 --json"
-当前 v0 版本已经实现了基础运行时:
+mutation_scope:
+ allowed_paths: ["ai/"]
-| 模块 | 当前已实现 |
-| --- | --- |
-| Governor | 确定性编排 planning、execution、evaluation、promotion、rollback 和 ledger 更新。 |
-| Sandbox | 基于 Git worktree 的实验隔离。候选变更只有被晋升后才会影响已接受分支。 |
-| 角色交接 | `planner`、`executor`、`evaluator` 作为隔离命令运行,并通过 JSON 文件通信。 |
-| 晋升模型 | 被接受的候选结果推进本地 `evolution/accepted` 分支;被拒绝的实验只保留记录,不推进该分支。 |
-| 首个适配器 | Token-Ignition 适配器,包含用于评估器进化的手写 golden set。 |
+hard_stops:
+ max_iterations: 30
+ max_consecutive_failures: 4
+ max_total_usd: 3.00
-## 目前还没有做什么
+llm:
+ provider: anthropic
+ model: claude-sonnet-4-6
+ api_key_env: ANTHROPIC_API_KEY
-| 尚未完成 | 为什么重要 |
-| --- | --- |
-| LLM-native planner/executor | 当前测试使用 fixture 脚本;真实 agent 接入是下一步。 |
-| 更强的进程/容器级沙箱 | Git worktree 能隔离文件,但 executor 和 evaluator 的运行隔离还应进一步增强。 |
-| 多目标适配器框架 | Token-Ignition 是第一个目标;还需要更多适配器来证明通用性。 |
-| 并行进化分支 | v0 目前聚焦单一 accepted 分支和简单晋升路径。 |
+coding_agent:
+ tool: aider
-## Roadmap
+roles:
+ planner: ["python3", "roles/planner.py"]
+ executor: ["bash", "roles/executor.sh"]
+ evaluator: ["python3", "roles/evaluator.py"]
+EOF
-- [ ] 增加 LLM 驱动的 planner 和 executor 实现。
-- [ ] 为 executor 和 evaluator 增加更强的沙箱隔离。
-- [ ] 将适配器接口从 Token-Ignition 推广为通用接口。
-- [ ] 增加多个不同类型项目的 examples。
-- [ ] 支持并行进化分支和更丰富的合并策略。
-- [ ] 改进 ledger 历史、晋升决策、拒绝候选的报告能力。
+# 3. 跑起来,放着不管
+evolution-kernel --config evolution.yml --repo /path/to/game --ledger /tmp/ledger --loop
+```
-## 文档
+---
-- [协议](docs/protocol.md)
-- [Token-Ignition 首个任务](docs/token-ignition-first-task.md)
+## 看它实际运行
-## 运行测试
+### 游戏 AI 胜率从 35% 进化到 72%——隔夜完成,无人值守
-```bash
-python3 -m unittest discover -s tests -v
-python3 adapters/token_ignition/evaluate_golden_cases.py
```
+进化前 ███░░░░░░░░░ 35% 胜率 (20 局输 13 局)
+进化后 ███████░░░░░ 72% 胜率 (20 局赢 14 局)
-## CLI 形状
+共 9 轮 · 花费 $2.14 · 你的时间投入:0 分钟
+```
-YAML 配置模式(MVP 主入口 — 包含 observer + scope + hard stops):
+循环逐轮发生的事情:
-```bash
-python3 -m evolution_kernel.cli \
- --config /path/to/evolution.yml \
- --repo /path/to/target-repo \
- --ledger /path/to/evolution-ledger
+```
+第 1 轮 观察: 胜率 35%
+ 规划 → "当前 AI 只会贪心取分,没有前瞻——加入 2 层 minimax 搜索"
+ 执行 → aider 重写 ai/strategy.py(改了 68 行)
+ 评估 → 胜率 51% ▲+16 — 接受
+ 提交 a3f1c9e "ai: 加入 minimax(35→51% 胜率)"
+
+第 2 轮 观察: 胜率 51%
+ 规划 → "minimax 没处理残局——加入位置评估权重"
+ 执行 → aider 新增 ai/eval_weights.py
+ 评估 → 胜率 58% ▲+7 — 接受
+ 提交 8b2de01 "ai: 位置权重(51→58%)"
+
+第 3 轮 观察: 胜率 58%
+ 规划 → "加入 alpha-beta 剪枝以搜索更深"
+ 执行 → aider 修改 ai/strategy.py
+ 评估 → 胜率 56% ▼-2 — 拒绝 连续失败次数: 1
+ 回滚 worktree 已丢弃 · 主分支没有任何变化
+
+第 4 轮 观察: 胜率 58% ← 历史记录显示第 3 轮 alpha-beta 失败
+ 规划 → "alpha-beta 导致了回退;改为根据失败模式分析调整残局权重"
+ 执行 → aider 调整 ai/eval_weights.py
+ 评估 → 胜率 67% ▲+9 — 接受
+ 提交 2c9af44 "ai: 残局权重调优(58→67%)"
+
+...
+
+第 9 轮 观察: 胜率 72%
+ 评估 → 72%——目标 60% 已超越——接受
+ 提交 9d7b321 "ai: 最终调优(70→72%)"
+
+{"halted": true, "reason": "max_iterations reached", "iterations": 30, "total_usd": 2.14, "total_tokens": 634000}
```
-旧版直接传参模式(保留以兼容原始的 golden-case 测试):
+> **第 3 轮是关键。** alpha-beta 剪枝让结果变*更差*,系统拒绝了这次变更,代码库保持不动。第 4 轮展示了 LLM 读取了拒绝历史并换了思路。这就是"有记忆"在实际中的含义——不会把同样的错误答案猜两遍。
+
+---
+
+## Ledger:完整的审计链
-```bash
-python3 -m evolution_kernel.cli \
- --repo /path/to/target-repo \
- --ledger /path/to/evolution-ledger \
- --goal /path/to/goal.json \
- --planner python3 /path/to/planner.py \
- --executor python3 /path/to/executor.py \
- --evaluator python3 /path/to/evaluator.py
+```
+ledger/
+ .evolution_state.json ← 预算计数器,进程重启后依然有效
+ runs/
+ 0001/
+ config.json ← 你的 evolution.yml 完整快照
+ observation.json ← evidence_sources 命令的原始输出
+ plan.json ← LLM 方案:摘要 · 步骤 · 预期改进
+ patch.diff ← 执行器实际应用的 diff
+ candidate_commit.txt ← 沙箱 commit 的 git SHA
+ evaluation.json ← 评估结果 + 指标 + cost_usd + tokens_used
+ decision.json ← 接受 / 拒绝 + 原因
+ reflection.json ← 注入下一轮历史的一行摘要
+ 0002/ ...
+ halted/
+ 20260501T120000Z.json ← 任何 hard stop 触发时写入
```
-熔断后清空持久化的 hard-stop 状态(不会触发一次 run):
+回滚一个 session 的所有变更:
```bash
-python3 -m evolution_kernel.cli --reset --ledger /path/to/evolution-ledger
+git checkout evolution/accepted
+git reset --hard # 每次接受的变更都是一个具名 commit
```
-每个角色命令都会收到:
+---
+
+## 架构
-```text
---input
---output
---worktree
+```mermaid
+flowchart LR
+ Config[evolution.yml] --> Governor
+
+ subgraph loop ["↻ 循环,直到 hard stop 触发"]
+ direction LR
+ Governor -->|"planner_input.json\n目标 · 观察 · 历史"| Planner["🧠 规划器\nLLM"]
+ Planner -->|plan.json| Executor["🔨 执行器\nAider / Claude Code"]
+ Executor -->|patch in git worktree| Evaluator["⚖️ 评估器\nLLM + shell"]
+ Evaluator -->|evaluation.json| Governor
+ end
+
+ Governor -->|"接受 → git commit"| Branch["evolution/accepted"]
+ Governor -->|"拒绝 → 丢弃"| Ledger[📁 Ledger]
+ Governor --> Ledger
```
-## MVP 使用方式(observer + scope + hard stops 闭环)
+**Governor 故意设计得"笨"。** 它是纯编排逻辑——零 LLM 调用。所有智能都在三个角色脚本里。换掉任何一个角色,Governor 只关心它读写的 JSON 文件。
+
+**角色之间通过文件通信,不共享内存。** 规划器不直接和执行器说话,评估器看不到执行器的自我评价。唯一的共享状态是 ledger。
-本 MVP 串起协议描述的完整闭环:
-`config -> observe -> plan/execute -> evaluate -> accept/reject -> ledger`。
+---
-### 1. 编写 `evolution.yml`
+## 当前能力
+
+| 功能 | 状态 |
+|---|:---:|
+| 多轮 LLM 循环,带记忆(历史注入) | ✅ |
+| 预算保护:`max_total_usd`、`max_total_tokens` | ✅ |
+| 迭代次数 / 连续失败次数 hard stop | ✅ |
+| 完整 ledger 审计链(进程重启后不丢失) | ✅ |
+| git worktree 沙箱——每次尝试完全隔离 | ✅ |
+| Scope 强制校验——`allowed_paths` 外的改动自动拒绝 | ✅ |
+| 配置驱动:随时切换 LLM 提供商、模型、coding agent | ✅ |
+| Aider 和 Claude Code executor 支持 | ✅ |
+| Anthropic 和 OpenAI 规划器 / 评估器支持 | ✅ |
+| 目标评估器——当 mission 完成时自动停止 | 🔧 PR #5 |
+| k 路并行探索(FunSearch / AlphaEvolve 模式) | 🔧 PR #6 |
+| 进程级沙箱(firejail / bwrap),面向生产环境 | 🔧 PR #7 |
+
+---
+
+## 配置参考
```yaml
-mission: "Add a minimal in-scope mutation so the evaluator accepts."
+# 必填——"更好"对你的项目意味着什么
+mission: "让游戏 AI 对内置对手的胜率达到 60% 以上"
+# 如何衡量当前状态
evidence_sources:
- - type: file
- path: metrics.json
- - type: shell
- command: "bash scripts/status.sh"
+ - type: shell # stdout 写入 observation.json
+ command: "python3 scripts/tournament.py --games 20 --json"
+ - type: file # 文件内容写入 observation.json
+ path: "metrics.json"
+# 只有这些路径下的文件允许被修改
mutation_scope:
allowed_paths:
- - "src/"
+ - "ai/" # 不在列表里的改动自动拒绝
+# 何时停止
hard_stops:
- max_iterations: 3
- max_consecutive_failures: 2
+ max_iterations: 30 # 总轮数
+ max_consecutive_failures: 4 # 连续拒绝多少次触发停止
+ max_total_usd: 3.00 # 0 = 不限制
+ max_total_tokens: 0 # 0 = 不限制
+
+# 规划器和评估器使用的 LLM
+llm:
+ provider: anthropic # anthropic | openai
+ model: claude-sonnet-4-6
+ api_key_env: ANTHROPIC_API_KEY
+
+# 执行器使用的 coding agent
+coding_agent:
+ tool: aider # aider | claude-code
+
+# 规划器每轮能看到多少轮历史
+history:
+ max_entries: 10
roles:
- planner: ["python3", "bots/planner.py"]
- executor: ["python3", "bots/executor.py"]
- evaluator: ["python3", "bots/evaluator.py"]
+ planner: ["python3", "roles/planner.py"]
+ executor: ["bash", "roles/executor.sh"]
+ evaluator: ["python3", "roles/evaluator.py"]
```
-`evidence_sources` 在 planner 运行前被读入 `observation.json`。
-`mutation_scope.allowed_paths` 在 executor 提交后被强制校验 —— 范围之外
-的任何改动都会被自动 reject,`decision.reason` 写为 `scope_violation: ...`。
-`hard_stops` 通过 `/.evolution_state.json` 跨 run 持久化,循环卡死
-时即使重启 CLI 也会被拦截。
+**切换到 OpenAI:**
+```yaml
+llm:
+ provider: openai
+ model: gpt-4o
+ api_key_env: OPENAI_API_KEY
+```
+
+**切换到 Claude Code:**
+```yaml
+coding_agent:
+ tool: claude-code
+```
-### 2. 跑一次实验
+---
+
+## CLI
```bash
-# 一次性:安装包(PyYAML 是唯一运行时依赖,已在 pyproject.toml 声明)
-python3 -m pip install -e .
+# 循环运行直到 hard stop 触发(推荐)
+evolution-kernel --config evolution.yml --repo /path/to/repo --ledger /tmp/ledger --loop
-# 一次性:准备目标仓库
-bash examples/demo_target/setup.sh
+# 只跑一轮
+evolution-kernel --config evolution.yml --repo /path/to/repo --ledger /tmp/ledger
-python3 -m evolution_kernel.cli \
- --config examples/evolution.yml \
- --repo examples/demo_target \
- --ledger /tmp/ek-ledger
+# 触发 halt 后重置预算计数器
+evolution-kernel --ledger /tmp/ledger --reset
```
-> 上面 `pip install -e .` 每个环境只需要做一次。之后那三行 CLI 命令是
-> 干净 checkout 下可复现的。
+退出码:`0` 正常结束 · `3` 被 hard stop 触发
+
+---
-需要重置熔断器从头来过:
+## 安装
```bash
-python3 -m evolution_kernel.cli --reset --ledger /tmp/ek-ledger
+pip install evolution-kernel
```
-### 3. 检查 ledger
+从源码安装(唯一运行时依赖:PyYAML):
-每一次 run 都会在 `/runs//` 下产出完整的证据链:
+```bash
+git clone https://github.com/Protocol-zero-0/evolution-kernel.git
+cd evolution-kernel
+pip install -e .
+```
+
+需要 Python 3.10 或更高版本。
-```text
-goal.json # 仅 legacy 模式
-config.json # 完整 YAML 配置快照(full 模式)
-observation.json # planning 之前 observer 收集到的证据
-plan.json # planner 输出
-patch.diff # baseline 与 candidate commit 之间的 diff
-candidate_commit.txt # sandbox 中 candidate commit 的 hash
-evaluation.json # evaluator 输出(scope_violation 时由 Governor 合成)
-decision.json # accept / reject + 原因
-reflection.json # 决策后的总结
+---
+
+## 运行测试
+
+```bash
+python3 -m pytest tests/ -v
```
-### 4. 验收标准 → 测试映射
+39 个测试 · 不需要网络连接 · 角色脚本由轻量 fixture 替代。
+
+---
-issue #1 中六条验收标准在 `tests/test_acceptance.py` 中各对应一个测试:
+## 自己写角色脚本
-| # | 验收要求 | 测试 |
-| - | --- | --- |
-| 1 | accept 推进 `evolution/accepted` | `test_accept_advances_accepted_branch` |
-| 2 | reject 不推进 | `test_reject_does_not_advance_accepted_branch` |
-| 3 | 强制 mutation scope + 记录违规 | `test_scope_violation_is_rejected_and_logged` |
-| 4 | observer 写出 `observation.json`(file + shell) | `test_observer_writes_observation_with_file_and_shell` |
-| 5 | hard stops 触发熔断后 `--reset` 恢复 | `test_hard_stop_blocks_then_reset_allows_via_cli` |
-| 6 | ledger 包含全部必需 artifact | `test_ledger_contains_all_required_artifacts` |
+每个角色是一个普通的可执行程序,接收三个参数:
-此外 `tests/test_scope.py` 单独钉死了 `allowed_paths` matcher 的边界语义
-(递归 / 精确匹配 / 兄弟名碰撞 / `..` 逃逸 / 空作用域 等)。
+```
+--input <路径> Governor 为这个角色准备的 JSON
+--output <路径> 角色退出前必须写入的 JSON
+--worktree <路径> 隔离 git 沙箱的 checkout 路径
+```
+
+`roles/planner.py`、`roles/executor.sh`、`roles/evaluator.py` 是参考实现。复制并修改它们,或者完全替换成 shell 脚本、Docker 调用——任何能读 `--input`、写 `--output` 的东西都行。
+
+---
-### 本 MVP 有意**不做**的内容
+## 项目结构
+
+```
+evolution_kernel/ 约 1,200 行运行时(Governor · Observer · HardStops · Config · CLI)
+roles/ 参考版规划器、执行器、评估器
+examples/ demo 目标仓库 + 可直接运行的 evolution.yml
+docs/ 协议文档
+tests/ 39 个单元 + 验收测试
+```
-按照 issue 的“不要做”清单:
+---
-- 不做 LLM / agent-swarm / dashboard。
-- 不做 PR router,不做自动 merge 到上游 `main`。
-- 不做多目标适配器框架 —— 唯一示例目标是 `examples/demo_target/`。
-- 不做超出 git worktree 的容器/进程级沙箱。
+## 许可证
-这些都是在内核本身被信任之后才适合做的下一步。
+MIT — 见 [LICENSE](LICENSE)。