# Butler

> 启动 Wiki 管家永续 loop。两队列系统（content/housekeeping）。每轮：W1队列选任务→W2执行→W3自评→记账，无需用户逐轮确认。每11轮discover+housekeeping-scan，每17轮执行ADM4-commit，每29轮W5反思，每37轮H17覆盖扫描。带 --auto 参数时忽略 fail 暂停 + 上下文将满时 ScheduleWakeup 自续。项目路径见 local/config.md。

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

---


启动时按以下顺序读取配置与规范：

**门控 — pypinyin 检查**：CJK wiki 必须先确认已安装 pypinyin（`python3 -c "import pypinyin"`），否则 butler 循环中创建中文页面时 `page_bucket.py` 会抛出 ImportError。缺失则提示用户安装并中止。

## 第一步：读取项目配置

```
local/config.md              ← 基础配置（WIKI_LANG、PORT、MEMEX_ROOT 等）
local/gene/_context.md       ← 本 wiki 专属执行上下文（若存在则读取）
local/butler/                ← butler 专属扩展（如目录存在）
  chapter-map.md             ← PN 章节映射表（各 wiki 专属）
  [其他扩展文件]
```

## 第二步：读取完整规范（W 层 skill）

从 `local/config.md` 中读取 `MEMEX_ROOT`，然后依次读取：

```
$MEMEX_ROOT/skills/SKILL_W0_Butler管家总则.md       — 角色、不变量、十步闭环、队列架构
$MEMEX_ROOT/skills/SKILL_W1_Butler探索队列.md  — 队列选取与发现策略
$MEMEX_ROOT/skills/SKILL_W2_Butler基因表达.md    — 基因执行框架（动作目录、WU 计费）
$MEMEX_ROOT/skills/SKILL_W3_Butler质量标准.md    — 质量评级（stub→premium）
$MEMEX_ROOT/skills/SKILL_W4_Butler评估检验.md  — 自评三问、accept/fail/skip
$MEMEX_ROOT/skills/SKILL_W5_Butler反思自改.md  — W5 反思触发与自改流程
$MEMEX_ROOT/skills/SKILL_W6_Butler标注规范.md — PN 标注格式
$MEMEX_ROOT/skills/SKILL_W7_引文真实性核验.md    — blockquote 核验
$MEMEX_ROOT/skills/SKILL_W9_Butler图式反思.md — W9 图式反思
$MEMEX_ROOT/skills/SKILL_W10_Butler内务整理.md   — 内务调度与健康指标
```

## 第三步：确认基因路径

基因发现优先级（W2 执行时）：
1. `local/gene/` — 本 wiki 独有的扩展基因（优先级最高）
2. `$MEMEX_ROOT/skills/gene/local/` — 本 wiki 对共享基因的覆盖
3. `$MEMEX_ROOT/skills/gene/` — 共享基因库

配置读取完毕后，执行 W0 十步闭环，永续运行。

## 基因表达日志要求

每轮 butler 循环对页面执行基因时，**必须**留下日志，规则如下：

### 每轮范围

每轮只选取 **一个基因**，对 **一组页面**（至少 5 页，由 `skills/butler/SKILL.md` 步骤 5 的 `batch_n = ceil(1000 / WU)` 公式确定，最小下限 5）执行处理。

### 日志位置与命名

日志写入 `logs/gene-express/`，文件名格式参照 BIOS spec pilot phase 约定：

```
YYYY-MM-DD-R{N}-{GENE}-{target}-{detail}.md
```

| 占位符 | 说明 |
|--------|------|
| `YYYY-MM-DD` | 执行当天日期 |
| `R{N}` | 本 wiki 的全局基因轮次计数器（整数，自 1 递增，存于 `logs/gene-express/.round` 或 `logs/butler/round_counter.txt`） |
| `{GENE}` | 基因代码，如 `CHK6`、`ENR3`、`SCN27` |
| `{target}` | 目标页面 slug 或类型名（多页时用类型名或简短描述） |
| `{detail}` | 可选后缀，表示子轮次或结果，如 `r1`、`pass`、`blocked`、`skip` |

示例：
- `2026-05-20-R1-CHK6-alan-turing-pass.md`
- `2026-05-20-R2-ENR3-concept-r1.md`
- `2026-05-20-R3-SCN27-person-r1.md`

### 日志内容（最小结构）

```markdown
---
round: {N}
date: YYYY-MM-DD
gene: {GENE}
pages: [slug1, slug2, ...]
result: pass | blocked | skip | partial
---

## 执行摘要

（一段话：做了什么、对哪些页面、主要发现）

## 页面处理记录

| 页面 | 操作 | 结果 | 备注 |
|------|------|------|------|
| slug | ...  | pass | ...  |

## 遗留问题

（若有：待后续轮次处理的问题或 defer 条目）
```

### 轮次计数器

每次写新日志前 `R += 1`。计数器优先读取 `logs/butler/round_counter.txt`（与 W0 共用）；若该文件不存在，在 `logs/gene-express/.round` 中维护独立计数。

---

## `--auto` 模式

触发条件：参数含 `--auto`。在普通永续 loop 之上覆盖两条暂停保护：

1. **忽略「连续 5 轮 fail」保护**
   原本连续 5 轮 fail 会立即中止 loop。`--auto` 下 fail 也继续下一轮，
   不因短期质量波动中断。fail 仍记账（W3 normal），fail 模式会进
   discover_by_broken_link 自纠正路径。

2. **上下文边界自续（ScheduleWakeup）**
   当本轮 release_round 之后判断剩余上下文 ≤ 10k token 时：
   - 完成当前轮 W3 记账 + release 锁（不留死锁）
   - 调用 `ScheduleWakeup({delaySeconds: 60, prompt: "/butler --auto", reason: "butler --auto 续跑（上下文将满）"})`
   - 主动结束当前会话；下次唤醒时从 `logs/butler/round_counter.txt` + `queue.md`
     状态继续，无缝接续

   状态全部已经持久化在 `logs/butler/`（round_counter、queue、actions 等），
   唤醒后从第一步重新启动即可。

**仍然有效的中止条件**（即使在 `--auto` 模式下）：
- 用户在新消息中明示「停止/pause」→ 立即中止，**不再** schedule
- `claim_round.py` 返回 `DUPLICATE`/`RACE` → 立即停止（避免双实例打架）
- 致命错误（脚本崩溃、git 不可用等）→ 报告后退出，不 schedule

| 暂停条件 | 默认（无 --auto）| `--auto` 模式 |
|---------|----------------|--------------|
| 用户说"停止/pause" | 立即停止 | 立即停止 |
| 连续 5 轮 fail | 停止 | 继续（fail 也跑下轮）|
| 上下文将满（剩 ~10k token）| 停止 | ScheduleWakeup 续跑 |
| claim_round 返回 RACE/DUPLICATE | 停止 | 停止（不 schedule）|
| 致命错误（脚本崩溃 / git 不可用）| 停止 | 停止（不 schedule）|

> 一句话：`--auto` 让 butler 在「质量小波动」和「上下文边界」两类原本会
> 触发暂停的情况下继续跑，其他保护机制不变。

