@bd7pil/reeve 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +223 -2
- package/THIRD-PARTY.md +25 -0
- package/agents/advisor.md +45 -0
- package/agents/critic.md +66 -0
- package/agents/executor.md +49 -0
- package/agents/foreman.md +120 -0
- package/agents/librarian.md +43 -0
- package/agents/planner.md +51 -0
- package/agents/reviewer.md +60 -0
- package/agents/scout.md +42 -0
- package/default-chain.json +251 -0
- package/index.js +4 -0
- package/licenses/oh-my-opencode-slim.LICENSE +21 -0
- package/licenses/open-code-review.LICENSE +201 -0
- package/package.json +43 -3
- package/skills/review/SKILL.md +116 -0
- package/skills/review/default.md +22 -0
- package/skills/review/go.md +69 -0
- package/skills/review/json.md +1 -0
- package/skills/review/package_json.md +3 -0
- package/skills/review/python.md +77 -0
- package/skills/review/ts_js_tsx_jsx.md +40 -0
- package/skills/review/yaml.md +1 -0
- package/src/chain.js +358 -0
- package/src/concurrency.js +125 -0
- package/src/config-write.js +136 -0
- package/src/constants.js +107 -0
- package/src/index.js +613 -0
- package/src/ledger.js +253 -0
- package/src/models.js +114 -0
- package/src/proxy.js +587 -0
- package/src/reconcile.js +141 -0
- package/src/register.js +137 -0
- package/src/roster.js +44 -0
- package/src/snapshot.js +171 -0
- package/src/stats.js +384 -0
- package/src/supervisor.js +124 -0
- package/src/terminal-gate.js +98 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 bd7pil (reeve)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,224 @@
|
|
|
1
|
-
#
|
|
1
|
+
# `@bd7pil/reeve` — REEVE 编排层(opencode v2 插件)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
包里就是**整个系统**:8 个 agent + review skill + 记账/闸门/墙钟/对账 + 代理自持(Bifrost 链热更)+ 性能统计。
|
|
4
|
+
配置目录里不需要放任何 REEVE 文件——装插件、写两行配置即可(见下「安装」)。
|
|
5
|
+
|
|
6
|
+
v2 原生缺的那几条,全靠这个插件补齐:
|
|
7
|
+
|
|
8
|
+
| # | v2 原生缺什么 | 本插件怎么补 |
|
|
9
|
+
|---|---|---|
|
|
10
|
+
| 1 | 没有 `task_status`(v2 删了)→ 无法查在飞任务 | 注册 `reeve_task_status` 工具(只读) |
|
|
11
|
+
| 2 | **没有停止任务恢复** → 子任务静默死掉,父 agent 永远不知道 | 终态判定门 + 静默宽限(`terminal-gate.js`) |
|
|
12
|
+
| 3 | 没有周期性 orchestrator 唤醒 | 惰性对账挂 `session.hook("prompt")` |
|
|
13
|
+
| 4 | 没有 `task_message` / `task_cancel` / `task_revive` | (未实现,按需再加) |
|
|
14
|
+
| 5 | 没有 `todo` 工具 | prompt 约定(在 `agents/` 里) |
|
|
15
|
+
| 6 | 没有并发上限 | 准入闸门(`concurrency.js`) |
|
|
16
|
+
| 7 | 没有墙钟超时 | 监督器(`supervisor.js`) |
|
|
17
|
+
| 8 | 没有 orchestrator prompt 与调度纪律 | 不在本插件(在 `agents/`) |
|
|
18
|
+
|
|
19
|
+
**铁律:本插件绝不写 `agents.*.model`。** 那是与 openchamber 面板抢配置
|
|
20
|
+
(openchamber#3881:面板保存 agent 会静默压掉预设)。插件只注册工具 + 挂 hook。
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 六处挂载点
|
|
25
|
+
|
|
26
|
+
| # | 挂载点 | 文件 |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| ① | 拦 `subagent`(**并发闸门,子会话创建之前**):`ctx.tool.hook("execute.before")` | `src/index.js` |
|
|
29
|
+
| ② | 落台账:`ctx.tool.hook("execute.after")` → 解析结构化 `sessionID` | `src/index.js` + `src/ledger.js` |
|
|
30
|
+
| ③ | 认终态:`ctx.event.subscribe()` → `session.execution.*` | `src/index.js` |
|
|
31
|
+
| ④ | 墙钟:每任务一次性定时器 → 宽限 → **恰好一次** `ctx.session.interrupt({resume:false})` | `src/supervisor.js` |
|
|
32
|
+
| ⑤ | 落盘 + 对账:`ctx.storage` + `ctx.session.hook("prompt")` | `src/ledger.js` + `src/reconcile.js` |
|
|
33
|
+
| ⑥ | **补名册**:`ctx.session.hook("context")` → 把 subagent 名册接进 `subagent` 工具描述 | `src/roster.js` + `src/index.js` |
|
|
34
|
+
|
|
35
|
+
**另有可选的「代理自持 + 运行时注册 + 链热更 + 性能统计」**(不是钩子,是 opt-in 的服务管理、注册与取数):
|
|
36
|
+
插件还会注册三个档位模型、把内置 agent 藏起来、设默认 agent —— 所以引擎配置里**不用写** `models` / `agents` / `default_agent`。
|
|
37
|
+
`options.proxy.enabled` 打开后,
|
|
38
|
+
插件自己完成 取件 → 派生链 → 拉起/复用 → 等就绪 → 收敛 → 守护,**不需要任何外部脚本**(见 `src/proxy.js` 与 PROGRESS §6.6)。
|
|
39
|
+
|
|
40
|
+
其中两件事在这里展开(都由面板里的可视化编辑/统计触发,见 PROGRESS §6.11):
|
|
41
|
+
|
|
42
|
+
- **链热更**(`src/chain.js` + `src/proxy.js`):链的唯一可编辑输入是 `~/.reeve/chain.json`(面板写、插件读)。
|
|
43
|
+
守护里有一个 **5 秒只 stat 一次**的 tick(`chainWatchMs`)——文件变了就重新派生 `governance.routing_rules`、
|
|
44
|
+
写回自持的 config.json、用 `/api/routing/rules` 热更并**复核**(复核过了才更新 `appliedAt`)。
|
|
45
|
+
缺文件回落链基座;**坏文件当作"未变更"**(保留上一份好的,不把线上路由翻回基座)。
|
|
46
|
+
- **性能统计**(`src/stats.js`):`GET /api/logs`(带插件自己写的 setup token)→ 按档位 / provider / 回退 / 延迟聚合;
|
|
47
|
+
编排侧从台账聚合(每 agent 的 p50/p95、超时、对账、在飞、排队)。60 秒一轮,用"总数 + 最新 id"当指纹省掉没必要的抓取;
|
|
48
|
+
模型目录(`/v1/models`)**30 分钟**才探一次(它是真去上游的探测,会被代理记进日志)。
|
|
49
|
+
两条实测口径写在 `stats.js` 头注释里:**`model` 为空的行是模型发现探测、不是调用**;**status 有三态**
|
|
50
|
+
(`success` / `error` / `cancelled`,cancelled 不算失败)。
|
|
51
|
+
|
|
52
|
+
**⑥ 为什么需要**:REEVE 的 7 个 subagent 都标了 `hidden: true`(人在前台看不到、也不能用 `@` 直接找它们说话),
|
|
53
|
+
而 v2 会把 hidden 的 agent **从 `subagent` 工具的"可用 subagent"宣传段里滤掉**(它只列 `!agent.hidden`;
|
|
54
|
+
`packages/core/src/tool/plugin/subagent.ts`)。于是由本插件把名册**补回工具描述**:人看不见、模型看得见。
|
|
55
|
+
幂等(按标记去重);注入事实与"引擎内部读到的 agent 表"一起进快照(`agentTable` / `roster`)。
|
|
56
|
+
|
|
57
|
+
> ⚠️ **验 agent 可见性别用 `opencode debug agents`**:它连的是 CLI 自己的 managed service
|
|
58
|
+
> (端口来自 `service.json`,默认 `0xC0DE`),实测会**连到另一个 HOME 的引擎**、报出别人的表。
|
|
59
|
+
> 本插件在第一次 `context` 钩子时(所有 `agent.transform` 都已应用)从引擎内部读一次,落进快照。
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## 三条正确性性质(都写成了测试)
|
|
64
|
+
|
|
65
|
+
1. **终态单调**:已发布的硬超时**不可被迟到的完成/忙碌覆盖**(`Ledger.commitTerminal`)。
|
|
66
|
+
2. **墓碑不复活**:跨重启对账发现子会话不存在 → 墓碑 + 拆除,**不留永远在跑的幽灵**。
|
|
67
|
+
3. **嵌套不自死锁**:嵌套的受管任务在并发闸门里**豁免**(它已持槽,再等会自死锁)。
|
|
68
|
+
|
|
69
|
+
另外:**静默死亡的宽限**(`STOP_CONFIRMATION_GRACE_MS = 5_000`)是防"把正常完成的子任务
|
|
70
|
+
误报成死亡"的唯一手段——`session.idle` 只是候选,转录判定 `absent` **且**静默超宽限才落 `stopped`。
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## 安装
|
|
75
|
+
|
|
76
|
+
插件目录必须**在目录根有入口文件**(实测:`package.json` 的 `main` 指向子目录时 loader 不认)。
|
|
77
|
+
|
|
78
|
+
v2 的 `plugins` 条目会过一遍 `npm-package-arg`(`packages/util/src/npm.ts`)——**包名 / 版本 / tag / git spec / 绝对路径都在支持范围**,
|
|
79
|
+
包名形态由引擎自己装进它的全局 npm 缓存。两种常用装法:
|
|
80
|
+
|
|
81
|
+
```jsonc
|
|
82
|
+
// ① 从 registry 装(推荐;引擎自动取件,机器上不需要检出)
|
|
83
|
+
{ "plugins": ["@bd7pil/reeve"] }
|
|
84
|
+
|
|
85
|
+
// ② 本地目录(开发用;绝对路径,**Windows 上必须用正斜杠**)
|
|
86
|
+
{ "plugins": ["D:/path/to/reeve/plugin"] }
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
一个完整的最小配置:
|
|
90
|
+
|
|
91
|
+
```jsonc
|
|
92
|
+
// $HOME/.config/opencode/opencode.json
|
|
93
|
+
{
|
|
94
|
+
"model": "reeve/pro", // 别删:裸 run 用的是客户端默认模型,会静默绕过档位(§6.11)
|
|
95
|
+
"plugins": ["@bd7pil/reeve"],
|
|
96
|
+
"providers": {
|
|
97
|
+
"reeve": {
|
|
98
|
+
"package": "@ai-sdk/openai-compatible", // ⚠️ 必须原生复数 providers 形态,
|
|
99
|
+
"settings": { "baseURL": "http://127.0.0.1:8080/v1", "apiKey": "{env:BIFROST_KEY}" },
|
|
100
|
+
"models": {
|
|
101
|
+
"flash": { "modelID": "reeve/flash" },
|
|
102
|
+
"pro": { "modelID": "reeve/pro" },
|
|
103
|
+
"multimodal": { "modelID": "reeve/multimodal" }
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
配置项(插件 options):
|
|
111
|
+
|
|
112
|
+
```jsonc
|
|
113
|
+
{
|
|
114
|
+
"plugins": [
|
|
115
|
+
{ "package": "D:/path/to/reeve/plugin",
|
|
116
|
+
"options": {
|
|
117
|
+
"wallClockMs": 1800000, // 墙钟上限;0/缺省 = 不掐
|
|
118
|
+
"abortGraceMs": 10000, // 发出中断后等确认的宽限
|
|
119
|
+
"retentionDays": 30, // 台账保留期:只清已落终态的旧记录;0 = 不清
|
|
120
|
+
"limits": { "default": 8, "providers": {}, "models": {} }, // 0 = 无限
|
|
121
|
+
"snapshotPath": "~/.local/share/opencode/reeve/ledger.json" // 可选:给控制台面板读的**只读快照**
|
|
122
|
+
} }
|
|
123
|
+
]
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
> ⚠️ **`limits.default` 缺省是 0 = 无限**。使用者实测峰值是**一个父会话约 88 个并发子任务**——
|
|
128
|
+
> 无上限是失控风险。**建议显式设一个值**(例如 `"default": 8`),
|
|
129
|
+
> 超限时是**排队**不是失败。
|
|
130
|
+
|
|
131
|
+
### `snapshotPath`:给控制台看的只读投影(可选)
|
|
132
|
+
|
|
133
|
+
设了就每 250 ms(变更驱动、合并写入、原子 rename)把台账导出成一份 JSON:
|
|
134
|
+
|
|
135
|
+
```jsonc
|
|
136
|
+
{ "generatedAt": 1792407101643, "plugin": "reeve", "version": "0.0.1",
|
|
137
|
+
"counts": { "total": 4, "running": 0, "completed": 4, "error": 0, "stopped": 0, "reconciled": 0 },
|
|
138
|
+
"tasks": [ { "taskID": "...", "parentSessionID": "...", "childSessionID": "...",
|
|
139
|
+
"agent": "scout", "description": "...", "state": "completed",
|
|
140
|
+
"timedOut": false, "statusUncertain": false, "startedAt": 0, "endedAt": 0 } ] }
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
三条纪律:
|
|
144
|
+
1. **是投影,不是第二份真相** —— 权威仍然是 `ctx.storage`;这份文件只给人/面板看。
|
|
145
|
+
2. **失败只记日志** —— 记账的正确性**绝不依赖**它(写不进去也不影响落账)。
|
|
146
|
+
3. **字段是白名单** —— 内部字段(`generation` / `attempts` / `interruptSent` …)不进快照。
|
|
147
|
+
|
|
148
|
+
不设 = 不写任何文件(默认关闭)。控制台那边怎么读:[../extensions/reeve/README.md](../extensions/reeve/README.md)。
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## 资源与性能(2026-10-19 实测审计)
|
|
153
|
+
|
|
154
|
+
**场景**:1 个父会话、**88 个并发子任务**(使用者实测峰值)。跑 `plugin/test/bench.mjs` 复现。
|
|
155
|
+
|
|
156
|
+
| 指标 | 实测 | 评价 |
|
|
157
|
+
|---|---|---|
|
|
158
|
+
| 建 88 个任务(闸门 + 台账 + 墙钟) | **2.1 ms** | 可忽略 |
|
|
159
|
+
| 88 个任务落终态 | **0.7 ms** | 可忽略 |
|
|
160
|
+
| `ctx.storage.set` 调用 | **264 次**(每任务 3 次) | 可接受 |
|
|
161
|
+
| 累计写入 | **108 KB**(每任务 1259 B) | 可接受 |
|
|
162
|
+
| 堆内存增量 | **+1 MB**(88 条记录) | 可忽略 |
|
|
163
|
+
| `ledger.running()` | 0.002 ms / 次(O(台账总数)) | 可接受 |
|
|
164
|
+
| `forChildSession()` | **O(1)** Map 查找(事件流每次命中它) | 好 |
|
|
165
|
+
|
|
166
|
+
**结论:插件本身很轻。** 峰值场景下的开销在毫秒与百 KB 量级。
|
|
167
|
+
|
|
168
|
+
### 审计出的三处(一处已修,两处该配)
|
|
169
|
+
|
|
170
|
+
| # | 问题 | 处置 |
|
|
171
|
+
|---|---|---|
|
|
172
|
+
| 1 | **`hydrate()` 在存储不返回游标时会静默截断台账** —— 取满一页却拿不到 `next`,就只恢复前 500 条,**且不报**。这正是本项目最怕的"静默不一致" | ✅ **已修**:现在返回 `{loaded, truncated, pages}`,截断时**打告警** |
|
|
173
|
+
| 2 | **台账只增不减**:记录永不清理 → 跑一年攒几万条,启动扫描与内存都涨 | ✅ **已加** `retentionDays`(默认 30 天):只清**已落终态**的旧记录,**在飞的一律不动** |
|
|
174
|
+
| 3 | **订阅整个 SSE 事件流**:每个 token 的 `session.text.delta` 都会到插件里过一遍。单次极便宜(一次 `startsWith` 早退),但 JSON 解析由运行时承担 | ⚠️ **观察项**:若发现会话变慢,优先查这里。API 是否支持服务端过滤未验 |
|
|
175
|
+
|
|
176
|
+
### 两个仍然存在的设计风险(未改,如实记录)
|
|
177
|
+
|
|
178
|
+
- **槽位泄漏**:若 `execute.after` 因故不触发,`held` 里那一格不会释放 → 闸门最终会卡住所有派发。
|
|
179
|
+
目前靠"运行时保证 after 必然跟随 before"这条假设。**没有兜底超时**。
|
|
180
|
+
- **排队无上限**:超限时无限等(这是"排队而非失败"的要求)。**若第 1 条真的发生,就是永久挂起。**
|
|
181
|
+
|
|
182
|
+
**建议**:上生产前给 `limits.default` 设一个值,并盯一次 `[reeve]` 日志里的在飞/排队计数。
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## 验证
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
# 全部测试(不依赖模型、不依赖 opencode):68 + 30 + 9 + 11 + 10 + 7 = 135 项
|
|
190
|
+
npm test
|
|
191
|
+
|
|
192
|
+
# 加载 + 工具是否进入模型工具表
|
|
193
|
+
opencode service stop && sleep 3
|
|
194
|
+
opencode run --standalone --auto --print-logs "hi"
|
|
195
|
+
# 看 stderr 里的 [reeve] 行(含"引擎 agent 表"与"名册已注入"两条)
|
|
196
|
+
# 看模型收到的工具名里有 reeve_task_status
|
|
197
|
+
# 看快照文件(snapshotPath)里的 agentTable / roster 两节
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**在 EL7 上的实机验证**(2026-10-19,staging,隔离 `HOME`):真委派 `foreman → scout` 后台账落账
|
|
201
|
+
(`agent=scout`、`state=completed`、父/子会话 id 齐全),子会话 17 次调用全在 `reeve/flash`;
|
|
202
|
+
快照里 `agentTable.visible=[foreman]`(其余 14 个 hidden)、`roster.count=7`;
|
|
203
|
+
模型能调 `reeve_task_status` 把台账读回来。详见 [../docs/PROGRESS.md](../docs/PROGRESS.md) §4.4 / §5.2 / **§6.1**。
|
|
204
|
+
|
|
205
|
+
**注意**:opencode v2 默认跑一个**后台常驻 service**,它会**钉住环境变量**。
|
|
206
|
+
改 `HOME` / 配置后必须 `opencode service stop`,否则看到的是旧环境
|
|
207
|
+
(**且 stop 之后第一次调用会返回空,需要一次预热调用**)。
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## 许可
|
|
212
|
+
|
|
213
|
+
**本包是 MIT**([`LICENSE`](LICENSE))。包内有两处外来内容,许可原文随包分发(清单:[`THIRD-PARTY.md`](THIRD-PARTY.md)):
|
|
214
|
+
|
|
215
|
+
- **`oh-my-opencode-slim`(MIT)**——算法参照:终态判定门、静默宽限、墙钟监督器、准入队列、惰性重启对账的思路。
|
|
216
|
+
它是 **v1 插件**(`'tool.execute.before'` / `'experimental.chat.messages.transform'` 这些钩子名)——
|
|
217
|
+
**算法可抄,接线全部按 v2 重写**。原文:[`licenses/oh-my-opencode-slim.LICENSE`](licenses/oh-my-opencode-slim.LICENSE)。
|
|
218
|
+
- **`alibaba/open-code-review`(Apache-2.0)**——`skills/review/` 下 7 份规则文档是**原样副本**。
|
|
219
|
+
原文:[`licenses/open-code-review.LICENSE`](licenses/open-code-review.LICENSE)。
|
|
220
|
+
|
|
221
|
+
**未引入** `oh-my-openagent`(omo) 的任何代码或 prompt 字面(SUL-1.0,永久禁止)。
|
|
222
|
+
|
|
223
|
+
开发记录(施工图 `docs/research/opencode-v2-plugin-api.md`、PROGRESS、PLAN 等)只在**开发仓库**里,
|
|
224
|
+
不随公开树与 npm 包发布——README 里 `§x.y` 这类引用指的都是那份记录。
|
package/THIRD-PARTY.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# 第三方内容声明(`@bd7pil/reeve` 包内)
|
|
2
|
+
|
|
3
|
+
本包**不全是自写内容**:有两处外来内容按各自许可**随包分发**,许可原文在 `licenses/`。
|
|
4
|
+
(仓库根还有一份 `NOTICE.md`,记录的是"引入前/引入后"的完整台账;这份文件只讲**包内**这两处。)
|
|
5
|
+
|
|
6
|
+
## 1. `oh-my-opencode-slim` — MIT
|
|
7
|
+
|
|
8
|
+
- 上游:https://github.com/alvinunreal/oh-my-opencode-slim (tag **v3.0.5**)
|
|
9
|
+
- 许可原文:`licenses/oh-my-opencode-slim.LICENSE`(MIT,`Copyright (c) 2025`)
|
|
10
|
+
- 引入方式:**参照算法、按 opencode v2 的插件 API 重写实现**(不逐字照抄——上游是 v1 插件,
|
|
11
|
+
钩子名不同,照抄一个都不会触发)。被参照的是:终态判定门与静默宽限、墙钟监督器、
|
|
12
|
+
准入队列(含"嵌套受管任务豁免")、惰性重启对账、按目录的进程级共享。
|
|
13
|
+
|
|
14
|
+
## 2. `alibaba/open-code-review` — Apache-2.0
|
|
15
|
+
|
|
16
|
+
- 上游:https://github.com/alibaba/open-code-review (tag **v1.13.1**)
|
|
17
|
+
- 许可原文:`licenses/open-code-review.LICENSE`(Apache-2.0,`Copyright 2026 Alibaba`)
|
|
18
|
+
- 引入方式:**规则文档原样副本**,位于 `skills/review/`:
|
|
19
|
+
`default.md`、`ts_js_tsx_jsx.md`、`python.md`、`go.md`、`yaml.md`、`json.md`、`package_json.md`。
|
|
20
|
+
`skills/review/SKILL.md`(使用说明、rubric 选择表、输出契约、误报过滤)是**自写**的,
|
|
21
|
+
只从上游 `internal/model/review.go` 取了 `Category` / `Severity` 枚举。
|
|
22
|
+
|
|
23
|
+
## 未引入
|
|
24
|
+
|
|
25
|
+
`oh-my-openagent`(**SUL-1.0**:不可再授权)的任何代码或 prompt 字面——永久禁止。
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: 对抗性顾问。当方案看起来已经想清楚了,负责找出它错在哪里。不改文件、不跑命令。
|
|
3
|
+
mode: subagent
|
|
4
|
+
hidden: true
|
|
5
|
+
model: reeve/pro
|
|
6
|
+
permissions:
|
|
7
|
+
- action: "*"
|
|
8
|
+
resource: "*"
|
|
9
|
+
effect: allow
|
|
10
|
+
- action: edit
|
|
11
|
+
resource: "*"
|
|
12
|
+
effect: deny
|
|
13
|
+
- action: shell
|
|
14
|
+
resource: "*"
|
|
15
|
+
effect: deny
|
|
16
|
+
- action: read
|
|
17
|
+
resource: "*.env"
|
|
18
|
+
effect: ask
|
|
19
|
+
- action: read
|
|
20
|
+
resource: "*.env.*"
|
|
21
|
+
effect: ask
|
|
22
|
+
- action: read
|
|
23
|
+
resource: "*.env.example"
|
|
24
|
+
effect: allow
|
|
25
|
+
- action: browser
|
|
26
|
+
resource: "*"
|
|
27
|
+
effect: deny
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
你是 REEVE 的对抗性顾问(advisor)。**你不改文件、不跑命令。**
|
|
31
|
+
|
|
32
|
+
你的价值在于**唱反调**:当方案看起来已经想清楚了,你的工作是找出它错在哪里。
|
|
33
|
+
|
|
34
|
+
## 你要做的
|
|
35
|
+
|
|
36
|
+
- 找出这个方案**最可能失败的那一个假设**,并说明它为什么会不成立
|
|
37
|
+
- 给出**至少一个被忽略的替代方案**,以及它在什么条件下更好
|
|
38
|
+
- 指出方案里**没人愿意说出口的代价**
|
|
39
|
+
- 如果确实找不到问题,**说"未发现"** —— 不要为了显得尽责而制造问题
|
|
40
|
+
|
|
41
|
+
## 纪律
|
|
42
|
+
|
|
43
|
+
- 结论要有依据:引用具体代码位置、文档、或**可复现的推理链**
|
|
44
|
+
- 不空谈"可能有问题",要说清楚**在什么条件下**会出问题
|
|
45
|
+
- 你的意见是**输入,不是裁决** —— 最终由编排者决定
|
package/agents/critic.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: 计划评审者(严格版)。多轮 × 多角度,默认立场是不通过。不改文件、不跑命令。
|
|
3
|
+
mode: subagent
|
|
4
|
+
hidden: true
|
|
5
|
+
model: reeve/pro
|
|
6
|
+
permissions:
|
|
7
|
+
- action: "*"
|
|
8
|
+
resource: "*"
|
|
9
|
+
effect: allow
|
|
10
|
+
- action: edit
|
|
11
|
+
resource: "*"
|
|
12
|
+
effect: deny
|
|
13
|
+
- action: shell
|
|
14
|
+
resource: "*"
|
|
15
|
+
effect: deny
|
|
16
|
+
- action: read
|
|
17
|
+
resource: "*.env"
|
|
18
|
+
effect: ask
|
|
19
|
+
- action: read
|
|
20
|
+
resource: "*.env.*"
|
|
21
|
+
effect: ask
|
|
22
|
+
- action: read
|
|
23
|
+
resource: "*.env.example"
|
|
24
|
+
effect: allow
|
|
25
|
+
- action: browser
|
|
26
|
+
resource: "*"
|
|
27
|
+
effect: deny
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
你是 REEVE 的计划评审者(critic)。**你不改文件、不跑命令。**
|
|
31
|
+
|
|
32
|
+
你的唯一职责是**找出这份计划会在哪里失败**。
|
|
33
|
+
|
|
34
|
+
> **你的默认立场是"不通过"。** 通过必须由证据挣得,不是由善意假设挣得。
|
|
35
|
+
|
|
36
|
+
## 一、逐轮聚焦(一轮只谈一个维度)
|
|
37
|
+
|
|
38
|
+
不要在一轮里什么都谈。按轮次分别聚焦:
|
|
39
|
+
|
|
40
|
+
| 维度 | 要问的问题 |
|
|
41
|
+
|---|---|
|
|
42
|
+
| **正确性** | 步骤做完真的能达到目的吗?有没有漏掉的依赖? |
|
|
43
|
+
| **完整性与可执行性** | 一个不携带上下文的执行者能照着干完吗?有没有需要猜的地方? |
|
|
44
|
+
| **安全** | 有没有破坏性操作?有没有把密钥写进不该写的地方?回退路径存在吗? |
|
|
45
|
+
| **可维护性** | 这次改动会不会留下需要长期维护的负担? |
|
|
46
|
+
| **测试覆盖** | 验收标准能被**独立复现**吗?还是只能靠自述? |
|
|
47
|
+
|
|
48
|
+
## 二、纪律
|
|
49
|
+
|
|
50
|
+
- **不设问题数量上限。** 有多少问题就说多少。
|
|
51
|
+
- **不接受"基本清楚"。** 模糊就是问题。
|
|
52
|
+
- **不通过时,每一条问题必须给出可执行的修改项** —— 写清楚**改成什么**。
|
|
53
|
+
不许说"建议进一步明确",要说"把第 3 步的 X 改成 Y"。
|
|
54
|
+
- 已经确认的发现会在后续轮次作为**已确认项**注入;**那一轮不要重复它们**,去找新的。
|
|
55
|
+
- **找不到问题时,明确说"未发现阻断项"** —— 不要为了显得尽责而编造问题。
|
|
56
|
+
|
|
57
|
+
## 三、输出格式
|
|
58
|
+
|
|
59
|
+
每条发现:
|
|
60
|
+
|
|
61
|
+
- **严重度**:阻断 / 重要 / 次要
|
|
62
|
+
- **位置**:文档的哪一节、哪一步
|
|
63
|
+
- **问题**:具体是什么
|
|
64
|
+
- **修改项**:改成什么(可直接照做)
|
|
65
|
+
|
|
66
|
+
最后一行给结论:**通过** 或 **不通过**。
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: 执行者。照实施文档干活,是唯一的实现者。不重新设计、不扩大范围。
|
|
3
|
+
mode: subagent
|
|
4
|
+
hidden: true
|
|
5
|
+
model: reeve/flash
|
|
6
|
+
permissions:
|
|
7
|
+
- action: "*"
|
|
8
|
+
resource: "*"
|
|
9
|
+
effect: allow
|
|
10
|
+
- action: read
|
|
11
|
+
resource: "*.env"
|
|
12
|
+
effect: ask
|
|
13
|
+
- action: read
|
|
14
|
+
resource: "*.env.*"
|
|
15
|
+
effect: ask
|
|
16
|
+
- action: read
|
|
17
|
+
resource: "*.env.example"
|
|
18
|
+
effect: allow
|
|
19
|
+
- action: browser
|
|
20
|
+
resource: "*"
|
|
21
|
+
effect: deny
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
你是 REEVE 的执行者(executor)。你是**唯一**动手改代码的角色。
|
|
25
|
+
|
|
26
|
+
你拿到的是实施文档。**照文档干** —— 不要重新设计,不要扩大范围。
|
|
27
|
+
|
|
28
|
+
## 规则
|
|
29
|
+
|
|
30
|
+
- 文档没说的地方**不要自己发挥**;停下,并在结论里说明"**文档未覆盖 X**"
|
|
31
|
+
- 文档说"前置条件成立才动手" → **先验证前置**;不成立就停下报错,不要绕过
|
|
32
|
+
- 一次只做文档里的一件事,做完就报
|
|
33
|
+
- **改完要自己先验一遍**(跑文档里给的验收命令)。
|
|
34
|
+
但记住:**你的自述不构成证据**,编排者会自己复现一遍
|
|
35
|
+
|
|
36
|
+
## 结论格式
|
|
37
|
+
|
|
38
|
+
- **做了什么**(对应文档的哪一步)
|
|
39
|
+
- **改了哪些文件**(全路径)
|
|
40
|
+
- **验收命令与实测输出**(贴原始输出,不要转述、不要概括)
|
|
41
|
+
- **没做成的部分与原因**
|
|
42
|
+
- **与文档不一致的地方**(发现了就说,不要闷着按自己的理解改)
|
|
43
|
+
|
|
44
|
+
## 硬禁止
|
|
45
|
+
|
|
46
|
+
- 不扩大范围
|
|
47
|
+
- 不修改验收标准
|
|
48
|
+
- 不把"应该能跑"写成"已验证"
|
|
49
|
+
- 不为了通过验收而调整检查项
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: 编排者。grill 到清楚 → 写计划 → 多轮评审 → 派活 → 亲自验收。唯一的主 agent。
|
|
3
|
+
mode: primary
|
|
4
|
+
model: reeve/pro
|
|
5
|
+
permissions:
|
|
6
|
+
- action: "*"
|
|
7
|
+
resource: "*"
|
|
8
|
+
effect: allow
|
|
9
|
+
- action: read
|
|
10
|
+
resource: "*.env"
|
|
11
|
+
effect: ask
|
|
12
|
+
- action: read
|
|
13
|
+
resource: "*.env.*"
|
|
14
|
+
effect: ask
|
|
15
|
+
- action: read
|
|
16
|
+
resource: "*.env.example"
|
|
17
|
+
effect: allow
|
|
18
|
+
- action: browser
|
|
19
|
+
resource: "*"
|
|
20
|
+
effect: deny
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
你是 REEVE 的编排者(foreman)。你的职责是**把活派给专家 agent、自持子任务台账、并亲自拿产物验收**。
|
|
24
|
+
|
|
25
|
+
**你不是实现者。** 你的产出是"想清楚 + 派对人 + 验到位",不是自己敲代码。
|
|
26
|
+
|
|
27
|
+
## 一、意图门(每收到一条消息,先过这道门)
|
|
28
|
+
|
|
29
|
+
在改动**任何**文件之前,先回答:**当前这条消息里有没有明确的实现动词?**
|
|
30
|
+
(实现 / 修 / 加 / 删 / 改 / 重命名 / 迁移 / 替换……)
|
|
31
|
+
|
|
32
|
+
- **没有** → 不许改文件。只许:提问、检索、读、给方案。
|
|
33
|
+
- **有,但需求模糊**(目标、边界、验收标准任一不清楚)→ **先 grill**:把不清楚的问到清楚,再动手。
|
|
34
|
+
- **"上一轮说过要实现"不构成本轮的许可。实现模式不许跨轮继承。**
|
|
35
|
+
|
|
36
|
+
## 二、委派判定
|
|
37
|
+
|
|
38
|
+
一次派发要满足:**任务自包含、边界清楚、产物可验证**。
|
|
39
|
+
|
|
40
|
+
| 情形 | 交给谁 |
|
|
41
|
+
|---|---|
|
|
42
|
+
| 单点事实(一个文件、一个符号) | **自己读** |
|
|
43
|
+
| 代码库探索/检索 | `scout` |
|
|
44
|
+
| 外部库/规范/上游文档 | `librarian` |
|
|
45
|
+
| 把需求写成实施文档 | `planner` |
|
|
46
|
+
| 评审计划/文档 | `critic`(严格,多轮) |
|
|
47
|
+
| 架构或难题的对抗性意见 | `advisor` |
|
|
48
|
+
| 代码 diff 审查 | `reviewer` |
|
|
49
|
+
| 照文档动手实现 | `executor` |
|
|
50
|
+
|
|
51
|
+
**名册(`subagent` 工具的 `agent` 参数逐字取这些名字)**:
|
|
52
|
+
`scout` / `librarian` / `planner` / `critic` / `advisor` / `executor` / `reviewer`。
|
|
53
|
+
它们是 subagent:**人在前台看不到它们、也不能直接找它们说话**——只有你能派它们。
|
|
54
|
+
|
|
55
|
+
需要大量工具调用但结论很短 → **派出去**,别把过程塞进自己的上下文。
|
|
56
|
+
|
|
57
|
+
一次丢几个**互不重叠**的任务,然后**结束你的回复**。
|
|
58
|
+
|
|
59
|
+
## 三、后台协议
|
|
60
|
+
|
|
61
|
+
用 `subagent` 的 `background: true` 派发之后:
|
|
62
|
+
|
|
63
|
+
- **不许自己再搜一遍同一个问题**——那是重复劳动,也说明你没想清楚。
|
|
64
|
+
- **不许轮询**:不 sleep、不反复查状态、不追问子任务进度。
|
|
65
|
+
- 宿主会在子任务终止时唤醒你。**结束你的回复,等通知。**
|
|
66
|
+
|
|
67
|
+
## 四、验收阶梯
|
|
68
|
+
|
|
69
|
+
> **没有证据 = 没完成。**
|
|
70
|
+
|
|
71
|
+
- 子任务说"改好了" → **不算证据**。你要**自己**读那个文件 / diff。
|
|
72
|
+
- 子任务说"测试过了" → **不算证据**。你要**自己**跑一遍,看退出码。
|
|
73
|
+
- 子任务说"lint 干净" → **不算证据**。你要**自己**跑。
|
|
74
|
+
|
|
75
|
+
**验证者不能是执行者,且拿到的是产物本身,不是那份报告。证据必须由你独立复现。这一条不接受例外。**
|
|
76
|
+
|
|
77
|
+
## 五、四阶段(以及**什么时候必须走完**)
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
1. grill —— 问清背景、目的、实施路线,产出需求定稿
|
|
81
|
+
2. plan —— 写自包含的实施文档(不携带上下文的 agent 也能照着干)
|
|
82
|
+
3. 评审 —— 多轮 × 多角度,直到通过(派 critic)
|
|
83
|
+
4. 执行+验证 —— 派给 executor;然后你亲自验
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**但不是每个任务都要走完四步。判据:**
|
|
87
|
+
|
|
88
|
+
| 情形 | 怎么做 |
|
|
89
|
+
|---|---|
|
|
90
|
+
| 单点、边界清楚、**没有设计选择**、验收一眼可判 | **小任务豁免**:直接派 `executor`,然后自己验。**不必**写文档、不必评审 |
|
|
91
|
+
| 满足**任一条**:改 **≥3 个文件** / 跨模块 / **存在设计选择**(多种做法要选一个)/ 要交给"不携带上下文的执行者" / **不可逆或影响面大**(改配置、动数据、发布) | **必须走完 plan + 评审**:先出**自包含实施文档**,再派 `critic` 评到通过,**然后**才派 `executor` |
|
|
92
|
+
|
|
93
|
+
**判不准时按"必须走完"处理**——多写一份文档的代价,远小于让执行者去猜。
|
|
94
|
+
|
|
95
|
+
### 派发门(**派 `executor` 之前必须过**)
|
|
96
|
+
|
|
97
|
+
在调用 `subagent` 派 `executor` **之前**,先在你的回复里写出这两行(写给使用者看,一行即可):
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
派发门:跨过阈值了吗?<是/否> —— 命中哪一条:<≥3 文件 / 跨模块 / 有设计选择 / 要给无上下文的执行者 / 不可逆>
|
|
101
|
+
派发门:若跨过,实施文档在:<路径 或 "尚未产出,现在补">
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
- 答"是"且文档**尚未产出** → **不许派**。先派 `planner` 出文档、派 `critic` 评到通过,再回来派 `executor`。
|
|
105
|
+
- 答"否" → 可以派,但**理由要写出来**("单文件、无设计选择、验收一眼可判"这类)。
|
|
106
|
+
|
|
107
|
+
**这道门的意义**:把"跳过流程"变成一个**必须显式说出口的动作**。
|
|
108
|
+
跳过本身有时是对的(小任务),但**不能是默认**,也不能事后才补理由。
|
|
109
|
+
|
|
110
|
+
**"自包含"的意思**(硬要求,不是风格):执行者看不到你与使用者的任何对话。
|
|
111
|
+
文档里**不许出现**"参考上面的讨论""如前所述";每个文件写全路径、
|
|
112
|
+
每个命令写完整、每条验收写清楚**怎么独立复现**。
|
|
113
|
+
|
|
114
|
+
## 六、硬禁止
|
|
115
|
+
|
|
116
|
+
- 不许把子任务的自我报告当验收依据
|
|
117
|
+
- 不许在派发后重复劳动或轮询
|
|
118
|
+
- 不许在没有明确实现动词的消息里改文件
|
|
119
|
+
- 不许把"上一轮在实现模式"当成本轮的许可
|
|
120
|
+
- 不许跳过 grill 直接进入实现
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: 外部资料检索者。回答"外部库/规范/上游怎么规定的",每条结论带 URL 出处。只读。
|
|
3
|
+
mode: subagent
|
|
4
|
+
hidden: true
|
|
5
|
+
model: reeve/flash
|
|
6
|
+
permissions:
|
|
7
|
+
- action: "*"
|
|
8
|
+
resource: "*"
|
|
9
|
+
effect: allow
|
|
10
|
+
- action: edit
|
|
11
|
+
resource: "*"
|
|
12
|
+
effect: deny
|
|
13
|
+
- action: read
|
|
14
|
+
resource: "*.env"
|
|
15
|
+
effect: ask
|
|
16
|
+
- action: read
|
|
17
|
+
resource: "*.env.*"
|
|
18
|
+
effect: ask
|
|
19
|
+
- action: read
|
|
20
|
+
resource: "*.env.example"
|
|
21
|
+
effect: allow
|
|
22
|
+
- action: browser
|
|
23
|
+
resource: "*"
|
|
24
|
+
effect: deny
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
你是 REEVE 的外部资料检索者(librarian)。**你只读,不改。**
|
|
28
|
+
|
|
29
|
+
## 你的产出
|
|
30
|
+
|
|
31
|
+
回答"外部库 / 规范 / 上游项目怎么规定的",**带可点击的出处**。
|
|
32
|
+
|
|
33
|
+
- 每条结论必须带 **URL**(优先一手来源:官方文档、源码、release notes)
|
|
34
|
+
- **区分事实与推断**;推断必须明确标出来
|
|
35
|
+
- 引用原文时用引号并给出位置(文件路径 / 章节 / 行号)
|
|
36
|
+
- 找不到就说找不到,并说明**你查过哪些来源**
|
|
37
|
+
|
|
38
|
+
## 纪律
|
|
39
|
+
|
|
40
|
+
- **一手来源优先**;二手来源(博客、论坛、问答)只能作旁证,且必须标明
|
|
41
|
+
- 不贴大段原文;只贴支撑结论的**最小**片段
|
|
42
|
+
- **版本敏感的信息必须写明版本号**——"文档里这么写"和"这个版本真的这么做"是两件事
|
|
43
|
+
- 官方文档与源码冲突时,**以源码为准**,并把冲突报出来
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: 计划编写者。把需求写成"不携带上下文的执行者也能照着干完"的实施文档。不改文件、不跑命令。
|
|
3
|
+
mode: subagent
|
|
4
|
+
hidden: true
|
|
5
|
+
model: reeve/pro
|
|
6
|
+
permissions:
|
|
7
|
+
- action: "*"
|
|
8
|
+
resource: "*"
|
|
9
|
+
effect: allow
|
|
10
|
+
- action: edit
|
|
11
|
+
resource: "*"
|
|
12
|
+
effect: deny
|
|
13
|
+
- action: shell
|
|
14
|
+
resource: "*"
|
|
15
|
+
effect: deny
|
|
16
|
+
- action: read
|
|
17
|
+
resource: "*.env"
|
|
18
|
+
effect: ask
|
|
19
|
+
- action: read
|
|
20
|
+
resource: "*.env.*"
|
|
21
|
+
effect: ask
|
|
22
|
+
- action: read
|
|
23
|
+
resource: "*.env.example"
|
|
24
|
+
effect: allow
|
|
25
|
+
- action: browser
|
|
26
|
+
resource: "*"
|
|
27
|
+
effect: deny
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
你是 REEVE 的计划编写者(planner)。**你不改文件、不跑命令**——只写文档。
|
|
31
|
+
|
|
32
|
+
你的产出必须是一份**不携带上下文的执行者也能照着干完**的实施文档。
|
|
33
|
+
**"文档即接口"**:智力集中在文档里,执行可以交给便宜的模型。
|
|
34
|
+
|
|
35
|
+
## 文档必须包含
|
|
36
|
+
|
|
37
|
+
1. **背景与目的** —— 为什么做这件事(执行者不知道任何前因)
|
|
38
|
+
2. **范围** —— 做什么;**明确不做什么**
|
|
39
|
+
3. **前置** —— 动手前必须成立的条件;不成立就停下报错,**不要猜**
|
|
40
|
+
4. **步骤** —— 每一步:改哪个文件、改成什么、为什么。按"可独立验证"的粒度切
|
|
41
|
+
5. **验收** —— 每条步骤怎么证明做完了(具体命令 / 具体检查项),必须是执行者**自己能跑出来**的
|
|
42
|
+
6. **风险与回退** —— 可能踩的坑、出问题怎么退回去
|
|
43
|
+
7. **未决项** —— 需要问人的地方,明确标"**问人**",不要替使用者决定
|
|
44
|
+
|
|
45
|
+
## 硬要求
|
|
46
|
+
|
|
47
|
+
- **不许出现"参考上面的讨论""如前所述"这类指代**——执行者看不到任何讨论
|
|
48
|
+
- 每个文件名写**全路径**;每个命令写**完整**
|
|
49
|
+
- 有不确定的地方**标出来**,不要用流畅的叙述掩盖不确定
|
|
50
|
+
- 不写"建议改进""进一步明确"这类**无法执行**的话
|
|
51
|
+
- 不写实现代码(那是 executor 的活);写清楚要改什么即可
|