baa-conductor

git clone 

commit
04fbd60
parent
0df67e3
author
codex@macbookpro
date
2026-03-31 20:35:54 +0800 CST
docs: define automation arbitration rules
4 files changed,  +291, -14
A plans/AUTOMATION_ARBITRATION_REQUIREMENTS.md
+184, -0
  1@@ -0,0 +1,184 @@
  2+# 自动化仲裁需求
  3+
  4+> 日期:2026-03-31
  5+> 状态:需求讨论
  6+
  7+## 背景
  8+
  9+当前系统已经有两类自动化能力:
 10+
 11+- BAA 指令系统:在 final-message 中提取 ` ```baa ` 指令并执行
 12+- 续命系统:在 final-message 结束后,通过 timed-jobs 生成并发送续命任务
 13+
 14+两者都会在 SSE / final-message 结束后开始工作。如果没有统一仲裁规则,就会出现同一对话中“指令执行”和“续命发送”同时争抢出站机会的问题。
 15+
 16+## 目标
 17+
 18+定义同一对话上的自动化优先级、互斥规则、暂停语义和救援语义,避免:
 19+
 20+- 一条 final-message 同时触发 BAA 与 renewal
 21+- BAA 正在执行时 renewal 继续向同一对话发消息
 22+- 对话进入死循环或持续报错时没有显式停机方式
 23+
 24+## 核心原则
 25+
 26+### 1. 显式控制优先于一切
 27+
 28+如果 final-message 中包含控制类指令,先处理控制,不再进入本轮普通 BAA 执行或续命。
 29+
 30+控制类指令包括:
 31+
 32+- 暂停当前对话
 33+- 恢复当前对话
 34+- 切换当前对话到 `manual / auto / paused`
 35+- 系统级暂停 / 恢复
 36+- 标记等待救援
 37+
 38+### 2. 显式执行优先于隐式续命
 39+
 40+如果 final-message 中包含普通 BAA 指令,则:
 41+
 42+- 先执行 BAA 指令
 43+- 本轮不生成续命任务
 44+
 45+续命只在“这一轮没有显式工作”时才运行。
 46+
 47+### 3. 同一对话同一时刻只能有一个自动化出站者
 48+
 49+对同一 local conversation,任一时刻只能处于以下之一:
 50+
 51+- `idle`
 52+- `instruction_running`
 53+- `renewal_running`
 54+
 55+不能同时存在两个自动化出站动作。
 56+
 57+### 4. 续命是空闲时的后台兜底,不是主逻辑
 58+
 59+续命只在以下条件同时满足时才允许运行:
 60+
 61+- 对话自动化状态为 `auto`
 62+- 系统级状态允许执行
 63+- 当前没有执行中的 BAA 指令
 64+- 当前没有执行中的 renewal
 65+- 没有命中熔断 / 救援等待状态
 66+
 67+## 同一条 final-message 的处理顺序
 68+
 69+收到最终权威消息后,按顺序处理:
 70+
 71+1. 控制类指令
 72+2. 普通 BAA 指令
 73+3. 续命判断
 74+
 75+也就是:
 76+
 77+- 有控制类指令:只做控制
 78+- 无控制类指令但有普通 BAA 指令:只做指令
 79+- 两者都没有:才考虑续命
 80+
 81+## 状态模型建议
 82+
 83+### 系统级
 84+
 85+- `running`
 86+- `paused`
 87+- `draining`
 88+
 89+### 对话级自动化状态
 90+
 91+- `manual`
 92+- `auto`
 93+- `paused`
 94+
 95+### 对话级暂停原因
 96+
 97+建议额外记录 `pause_reason`,至少支持:
 98+
 99+- `user_pause`
100+- `ai_pause`
101+- `system_pause`
102+- `error_loop`
103+- `rescue_wait`
104+
105+### 对话级执行锁
106+
107+建议运行态表达为:
108+
109+- `idle`
110+- `instruction_running`
111+- `renewal_running`
112+
113+## AI 自行停机与救援语义
114+
115+AI 需要能够在“持续出错、陷入死循环、需要人工或其他 AI 接手”时显式停机。
116+
117+这里不依赖自然语言猜测,而是要求 AI 发出明确控制指令。
118+
119+推荐语义:
120+
121+- AI 发现自己无法继续安全推进时:
122+  - 暂停当前对话
123+  - 原因设为 `rescue_wait`
124+- 其他 AI 或人工介入后:
125+  - 显式恢复该对话
126+  - 或切到 `manual`
127+  - 或重新切回 `auto`
128+
129+## 建议的 BAA 控制指令草案
130+
131+沿用旧 `baa` 的 `@target::tool::params` 风格,优先采用显式 JSON 参数。
132+
133+### 系统级
134+
135+```text
136+@conductor::system::pause
137+@conductor::system::resume
138+```
139+
140+### 当前对话
141+
142+```text
143+@conductor::conversation::pause::{"scope":"current","reason":"rescue_wait"}
144+@conductor::conversation::resume::{"scope":"current"}
145+@conductor::conversation::mode::{"scope":"current","mode":"manual"}
146+@conductor::conversation::mode::{"scope":"current","mode":"auto"}
147+@conductor::conversation::mode::{"scope":"current","mode":"paused"}
148+```
149+
150+### 指令约束
151+
152+- `scope:"current"` 表示当前 final-message 所属对话
153+- `pause` 和 `mode:"paused"` 都可以让对话停机,但 `pause` 更适合带原因
154+- `resume` 只解除当前对话暂停,不改系统级状态
155+- `system::resume` 只恢复系统级闸门,不改各对话原有状态
156+
157+## 熔断建议
158+
159+当出现下面情况时,系统应允许自动进入 `paused` 或 `rescue_wait`:
160+
161+- 同一对话短时间连续失败
162+- 续命内容高度重复,疑似死循环
163+- BAA 指令连续报错
164+- 指令和续命交替触发,形成无意义回路
165+
166+熔断后:
167+
168+- 停止继续续命
169+- 不再自动触发新的对话级执行
170+- 记录原因和最近错误
171+- 等待人工或其他 AI 恢复
172+
173+## 与现有需求文档的关系
174+
175+- 页面/对话级统一控制:见 `UNIFIED_OVERLAY_AUTOMATION_CONTROL.md`
176+- 系统级暂停:见 `SYSTEM_LEVEL_PAUSE_REQUIREMENTS.md`
177+- 本文档只回答“同一对话在 SSE 结束后先做什么、谁优先、什么时候该停机”
178+
179+## 验收标准
180+
181+- 同一条 final-message 不会同时触发 BAA 执行和 renewal 发送
182+- 控制类指令优先于普通 BAA 与 renewal
183+- BAA 指令执行时,renewal 不会抢同一对话的出站机会
184+- 对话可被 AI 显式切到 `rescue_wait` / `paused`
185+- 系统恢复和对话恢复不会互相覆盖状态
M plans/BAA_INSTRUCTION_ROADMAP.md
+22, -0
 1@@ -13,6 +13,7 @@
 2 
 3 - [`./ARTIFACT_STATIC_SERVICE.md`](./ARTIFACT_STATIC_SERVICE.md)(下一阶段主线)
 4 - [`./BAA_INSTRUCTION_SYSTEM.md`](./BAA_INSTRUCTION_SYSTEM.md)
 5+- [`./AUTOMATION_ARBITRATION_REQUIREMENTS.md`](./AUTOMATION_ARBITRATION_REQUIREMENTS.md)
 6 - [`./STATUS_SUMMARY.md`](./STATUS_SUMMARY.md)
 7 - [`./archive/BAA_BROWSER_PROXY_DELIVERY_REQUIREMENTS.md`](./archive/BAA_BROWSER_PROXY_DELIVERY_REQUIREMENTS.md)
 8 
 9@@ -68,6 +69,7 @@
10 未来可扩的 tool 面包括:
11 
12 - 更完整的 `browser.*`
13+- automation control plane(系统级暂停、对话级 pause/resume/mode)
14 - `codex/sessions`
15 - `codex/turn`
16 - `tasks`
17@@ -79,6 +81,26 @@
18 - 插件仍保持 thin-plugin
19 - 解析、路由、权限、审计都不回流到插件
20 
21+### 4.1 自动化控制面
22+
23+未来的 BAA 指令系统应补齐显式控制能力,而不是继续依赖自然语言猜测“现在该暂停还是继续”。
24+
25+优先方向:
26+
27+- `@conductor::system::pause`
28+- `@conductor::system::resume`
29+- `@conductor::conversation::pause`
30+- `@conductor::conversation::resume`
31+- `@conductor::conversation::mode`
32+
33+这些控制指令与 renewal 的关系不是“谁替代谁”,而是共享同一套 automation control plane。
34+
35+仲裁原则固定为:
36+
37+- 控制类指令优先于普通 BAA 指令
38+- 普通 BAA 指令优先于续命
39+- 续命只在对话空闲时运行
40+
41 ## 5. 编排层路线
42 
43 当前主线仍是单节点、单轮主线。后续路线图包括:
M plans/SYSTEM_LEVEL_PAUSE_REQUIREMENTS.md
+23, -2
 1@@ -9,6 +9,8 @@
 2 
 3 需要一个系统级暂停,一键暂停所有自动化行为。
 4 
 5+同一对话在 SSE 结束后的优先级与互斥规则,另见 `AUTOMATION_ARBITRATION_REQUIREMENTS.md`。
 6+
 7 ## 当前现状
 8 
 9 | 控制层级 | BAA 指令 | 续命系统 |
10@@ -20,6 +22,8 @@
11 
12 增加系统级暂停能力,一键暂停/恢复所有自动化(BAA 指令 + 续命)。
13 
14+这里的系统级暂停是独立于页面/对话级状态的上层闸门,不与 `manual / auto / paused` 合并。
15+
16 ## 设计要点
17 
18 ### 系统级暂停语义
19@@ -29,6 +33,12 @@
20 - 系统暂停不改变各对话的 automation_status,只是在更上层阻断执行
21 - 系统恢复后,各对话按自己的 automation_status 恢复原有行为
22 
23+换句话说:
24+
25+- 系统级暂停是“先别跑任何自动化”
26+- 对话级暂停是“只有这个对话别跑”
27+- 两者可以同时存在,但绝不能互相覆盖状态
28+
29 ### 与页面/对话级的关系
30 
31 ```
32@@ -37,6 +47,16 @@
33 对话级暂停 → 只影响该对话,其他对话不受影响
34 ```
35 
36+执行顺序固定为:
37+
38+1. 先看系统级状态
39+2. 再看页面/对话级状态
40+
41+这意味着:
42+
43+- 系统级恢复不会把 `manual` 或 `paused` 的对话自动改成 `auto`
44+- 页面级恢复不会把系统级 `paused` 改成 `running`
45+
46 ### 实现方向
47 
48 - 复用现有 `system_state` 表的 `automation` key
49@@ -46,8 +66,9 @@
50 ### 控制入口
51 
52 - 浮层里保留系统级控制按钮(当前已有)
53+- 浮层可以与页面级控制放在同一块 UI 里,但必须分成两个区域,不共用一个按钮或一个状态值
54 - REST API:复用现有 `/v1/control/state` 或新增 `/v1/system/pause`、`/v1/system/resume`
55-- 后续可通过 BAA 指令 `@conductor::system::pause` 控制
56+- 后续可通过 BAA 指令 `@conductor::system::pause` / `@conductor::system::resume` 控制
57 
58 ## 验收标准
59 
60@@ -59,4 +80,4 @@
61 
62 ## 优先级
63 
64-中。当前页面/对话级控制合并是优先项,系统级暂停可以后做。
65+中。当前优先项是“统一浮层入口但保持分层状态模型”;系统级暂停在此之后实现。
M plans/UNIFIED_OVERLAY_AUTOMATION_CONTROL.md
+62, -12
  1@@ -7,7 +7,9 @@
  2 
  3 当前 Firefox 插件右下角浮层控制的是 BAA 指令处理的暂停/恢复。续命系统的对话自动化状态(manual/auto/paused)完全独立,只能通过 REST API 操作。用户无法从浮层上看到或控制续命行为。
  4 
  5-这两套自动化本质上都是"这个页面/对话是否允许 conductor 自动处理",应该合并为一个统一的控制入口。
  6+这两套自动化本质上都是“这个页面/对话是否允许 conductor 自动处理”,应该统一到一个控制入口里;但它们和系统级暂停不是同一层语义,不能压成一个总状态机。
  7+
  8+同一对话在 SSE 结束后的执行优先级,另见 `AUTOMATION_ARBITRATION_REQUIREMENTS.md`。
  9 
 10 ## 当前现状
 11 
 12@@ -30,32 +32,72 @@
 13 
 14 ## 目标
 15 
 16-将 BAA 指令处理和续命自动化合并为一个统一的页面/对话级控制,从浮层一个按钮控制。
 17+将 BAA 指令处理和续命自动化统一到一个页面/对话级控制入口,从浮层一个位置查看和操作。
 18+
 19+明确不做的事:
 20+
 21+- 不把系统级 `running / paused / draining` 和对话级 `manual / auto / paused` 合并成一个状态值
 22+- 不让“恢复本页”顺手解除系统级暂停
 23+- 不让“系统恢复”顺手修改各对话原有的 `manual / auto / paused`
 24+
 25+## 分层状态模型
 26+
 27+### 系统级(保持独立)
 28 
 29-## 合并后的语义
 30+- `running`
 31+- `paused`
 32+- `draining`
 33 
 34-页面/对话级统一自动化状态:
 35+系统级状态继续作为最外层闸门,控制整机自动化是否允许执行。
 36+
 37+### 页面/对话级(统一控制)
 38+
 39+页面/对话级继续使用统一自动化状态:
 40 
 41 - **自动**(auto):BAA 指令正常处理 + 续命系统正常运行
 42 - **暂停**(paused):BAA 指令暂停 + 续命系统暂停(不生成新任务,待执行任务不推进,执行中任务自然结束)
 43 - **手动**(manual):BAA 指令暂停 + 续命系统不生成任务
 44 
 45+页面/对话级只回答“当前页面/对话是否允许自动化”;系统级只回答“整个 conductor 现在是否允许自动化”。
 46+
 47+## 执行判定顺序
 48+
 49+执行时按下面顺序判断:
 50+
 51+1. 先看系统级状态
 52+2. 再看页面/对话级状态
 53+
 54+也就是:
 55+
 56+- 系统级 `paused` 时,不管当前对话是 `auto` 还是 `manual / paused`,都统一不执行
 57+- 系统级恢复后,再按当前对话自己的 `manual / auto / paused` 决定是否继续
 58+
 59 ## 控制入口
 60 
 61 ### 浮层(首要入口)
 62 
 63-- 当前"暂停本页"/"恢复本页"按钮改为同时控制两套系统
 64-- 浮层显示当前对话的统一状态(auto/paused/manual)
 65-- 点击切换时,同时更新 page_control 和 renewal automation_status
 66+- 当前“暂停本页”/“恢复本页”按钮改为同时控制页面级 BAA 与 renewal
 67+- 浮层同时显示两类状态:
 68+  - 系统:运行中 / 系统暂停 / draining
 69+  - 当前对话:auto / paused / manual
 70+- 按钮文案保持分层:
 71+  - 系统级按钮:`系统暂停` / `系统恢复`
 72+  - 页面级按钮:`暂停本页` / `恢复本页` / `设为手动`
 73+- 点击页面级按钮时,只更新 page_control 和 renewal automation_status,不修改系统级状态
 74 
 75 ### REST API(保留)
 76 
 77 - `/v1/renewal/conversations/:id/auto` 等接口保留
 78-- 但状态变更需要同步到 page_control,保持一致
 79+- 但状态变更需要同步到 page_control,保持页面级一致
 80+- REST API 如果改的是系统级状态,只能改系统级,不碰各对话状态
 81 
 82 ### BAA 指令(后续)
 83 
 84-- 后期可以通过 `@conductor::renewal::auto` 等指令控制,但不是当前任务
 85+- 后期可以通过显式 BAA 控制指令控制,例如:
 86+  - `@conductor::conversation::pause::{"scope":"current","reason":"rescue_wait"}`
 87+  - `@conductor::conversation::resume::{"scope":"current"}`
 88+  - `@conductor::conversation::mode::{"scope":"current","mode":"auto"}`
 89+- 具体仲裁规则见 `AUTOMATION_ARBITRATION_REQUIREMENTS.md`
 90 
 91 ## 实现要点
 92 
 93@@ -76,17 +118,25 @@
 94 REST API → conductor → 广播 WS → controller → 浮层刷新
 95 ```
 96 
 97+系统级同步方向保持独立:
 98+
 99+```
100+系统暂停/恢复按钮 or REST API → conductor → 更新 system_state.automation → 广播 WS → 浮层刷新
101+```
102+
103 ## 需要注意
104 
105 - 新对话默认 `manual`,用户必须主动设为 `auto` 才会续命
106-- "暂停本页"同时暂停两套系统,"恢复本页"恢复到暂停前的状态
107+- “暂停本页”同时暂停页面级 BAA 和 renewal
108+- “恢复本页”只恢复当前对话,不解除系统级暂停
109+- “系统恢复”只恢复系统级闸门,不改各对话原有状态
110 - 如果对话还没有 local_conversation 记录(从没有 final-message),浮层只控制 page_control
111-- 系统级暂停(全局暂停所有自动化)不在本需求范围内,见 `SYSTEM_LEVEL_PAUSE_REQUIREMENTS.md`
112+- 系统级暂停仍是独立需求,见 `SYSTEM_LEVEL_PAUSE_REQUIREMENTS.md`
113 
114 ## 验收标准
115 
116 - 浮层点击"暂停本页"后,BAA 指令和续命同时暂停
117 - 浮层点击"恢复本页"后,两者同时恢复
118-- 浮层显示当前对话的统一状态
119+- 浮层能同时显示系统状态和当前对话状态
120 - REST API 修改状态后,浮层能实时反映
121 - 不影响现有 BAA 指令主链路