baa-conductor

git clone 

commit
264650f
parent
42670d0
author
im_wower
date
2026-04-01 15:44:51 +0800 CST
docs: 风险项拆分为任务 — T-S066 风控持久化 / T-S067 Gemini raw relay / T-S068 ChatGPT 冷启动保护 / T-S069 delivery 确认增强
4 files changed,  +400, -0
A tasks/T-S066.md
+101, -0
  1@@ -0,0 +1,101 @@
  2+# Task T-S066:风控状态持久化 — 重启后恢复限流/退避/熔断计数
  3+
  4+## 状态
  5+
  6+- 当前状态:`待开始`
  7+- 规模预估:`M`
  8+- 依赖任务:`T-S060`
  9+- 建议执行者:`Codex`
 10+
 11+## 直接给对话的提示词
 12+
 13+读 `/Users/george/code/baa-conductor/tasks/T-S066.md` 任务文档,完成开发任务。
 14+
 15+如需补背景,再读:
 16+
 17+- `/Users/george/code/baa-conductor/plans/AUTOMATION_ARBITRATION_REQUIREMENTS.md`
 18+- `/Users/george/code/baa-conductor/tasks/TASK_OVERVIEW.md`
 19+
 20+## 当前基线
 21+
 22+- 仓库:`/Users/george/code/baa-conductor`
 23+- 分支基线:`main`
 24+
 25+## 分支与 worktree(强制)
 26+
 27+- 分支名:`feat/persistent-rate-limit-state`
 28+- worktree 路径:`/Users/george/code/baa-conductor-persistent-rate-limit-state`
 29+
 30+开工步骤:
 31+
 32+1. `cd /Users/george/code/baa-conductor`
 33+2. `git worktree add ../baa-conductor-persistent-rate-limit-state -b feat/persistent-rate-limit-state main`
 34+3. `cd ../baa-conductor-persistent-rate-limit-state`
 35+
 36+## 风险描述
 37+
 38+当前风控状态(限流计数、退避窗口、熔断标记)全部保存在进程内存中。conductor 重启后这些状态全部丢失,意味着:
 39+
 40+- 刚触发限流的对话重启后立即恢复发送
 41+- 正在退避的 renewal job 重启后立即重试
 42+- 已经熔断的通道重启后重新激活
 43+
 44+对于高频续命场景,这可能导致重启后短时间内大量请求涌向上游 AI 平台。
 45+
 46+## 目标
 47+
 48+将关键风控状态持久化到 `artifact.db` 或 `system_state`,使 conductor 重启后能恢复到上次的风控位置。
 49+
 50+## 范围
 51+
 52+- 识别需要持久化的风控状态(至少包括:对话级限流计数、退避窗口、熔断标记、`pause_reason`)
 53+- 选择存储方案(扩展 `local_conversations` 字段 / 独立 `rate_limit_state` 表 / `system_state` KV)
 54+- 在 conductor 启动时从持久化层恢复风控状态
 55+- 在风控状态变更时写入持久化层(不要求每次都同步写,可以定期批量)
 56+- 确保持久化写入不阻塞主流程
 57+
 58+## 路径约束
 59+
 60+- 持久化层必须复用现有 `artifact.db` 体系
 61+- 恢复逻辑不能拖慢 conductor 启动时间超过 1 秒
 62+- 不要求所有内存态都持久化,只持久化"重启后丢失会导致问题"的关键状态
 63+
 64+## 需要特别注意
 65+
 66+- `cooldownUntil` 已经持久化在 `local_conversations`,这部分不需要重复做
 67+- `renewal_jobs` 的 `next_attempt_at` 也已持久化,退避窗口不会丢失
 68+- 真正需要补的是:仲裁模块的执行锁状态、熔断计数器、对话级限流窗口
 69+- 持久化频率要权衡性能:每次变更都写太频繁,但纯靠定时写可能在崩溃时丢数据
 70+
 71+## 验收标准
 72+
 73+- conductor 重启后,正在熔断的通道不会立即恢复
 74+- conductor 重启后,限流窗口内的对话不会立即恢复发送
 75+- 持久化写入不影响正常请求延迟
 76+- 新增存储不破坏现有 schema 和 D1 同步
 77+
 78+## 执行记录
 79+
 80+> 以下内容由执行任务的 AI 填写,创建任务时留空。
 81+
 82+### 开始执行
 83+
 84+- 执行者:
 85+- 开始时间:
 86+- 状态变更:`待开始` → `进行中`
 87+
 88+### 完成摘要
 89+
 90+- 完成时间:
 91+- 状态变更:`进行中` → `已完成`
 92+- 修改了哪些文件:
 93+- 核心实现思路:
 94+- 跑了哪些测试:
 95+
 96+### 执行过程中遇到的问题
 97+
 98+- 
 99+
100+### 剩余风险
101+
102+- 
A tasks/T-S067.md
+95, -0
 1@@ -0,0 +1,95 @@
 2+# Task T-S067:Gemini 正式接入 raw relay 支持面
 3+
 4+## 状态
 5+
 6+- 当前状态:`待开始`
 7+- 规模预估:`M`
 8+- 依赖任务:无
 9+- 建议执行者:`Codex`
10+
11+## 直接给对话的提示词
12+
13+读 `/Users/george/code/baa-conductor/tasks/T-S067.md` 任务文档,完成开发任务。
14+
15+如需补背景,再读:
16+
17+- `/Users/george/code/baa-conductor/plans/BAA_INSTRUCTION_SYSTEM.md`
18+- `/Users/george/code/baa-conductor/plans/BAA_INSTRUCTION_ROADMAP.md`
19+- `/Users/george/code/baa-conductor/plugins/baa-firefox/README.md`
20+
21+## 当前基线
22+
23+- 仓库:`/Users/george/code/baa-conductor`
24+- 分支基线:`main`
25+
26+## 分支与 worktree(强制)
27+
28+- 分支名:`feat/gemini-raw-relay`
29+- worktree 路径:`/Users/george/code/baa-conductor-gemini-raw-relay`
30+
31+开工步骤:
32+
33+1. `cd /Users/george/code/baa-conductor`
34+2. `git worktree add ../baa-conductor-gemini-raw-relay -b feat/gemini-raw-relay main`
35+3. `cd ../baa-conductor-gemini-raw-relay`
36+
37+## 风险描述
38+
39+Gemini 当前不是 `/v1/browser/request` 的正式 raw relay 支持面。`@browser.gemini` 走 helper/proxy 混合路径,仍需依赖最近观测到的真实请求上下文。当插件刚启动或长时间未捕获到 Gemini 真实请求时,delivery 可能静默失败或退回不稳定路径。
40+
41+## 目标
42+
43+将 Gemini 提升为与 ChatGPT/Claude 同等的正式 raw relay 支持面,使 `@browser.gemini` 能稳定通过 `browser.proxy_delivery` 直接派发请求。
44+
45+## 范围
46+
47+- 分析 Gemini SSE/HTTP 请求结构,确定可稳定复用的请求模板
48+- 在插件侧为 Gemini 实现与 ChatGPT 同级的请求模板捕获和缓存机制
49+- 在 conductor 侧为 Gemini 补齐 raw relay 路由和模板匹配逻辑
50+- 验证 Gemini 新对话、已有对话、多轮对话场景下的 proxy delivery 稳定性
51+
52+## 路径约束
53+
54+- 不改变现有 ChatGPT/Claude 的 delivery 路径
55+- Gemini 的请求结构特殊(`f.req` 编码),需要在插件侧做好模板提取
56+- 如果 Gemini 的请求结构不适合做完整 raw relay,也可以选择强化 helper 路径的稳定性,但需要在文档中说明取舍
57+
58+## 需要特别注意
59+
60+- Gemini 的请求格式是 URL-encoded form data,不是 JSON,模板化难度比 ChatGPT 大
61+- Gemini 的 conversation_id 提取已经在 `final-message.js` 里实现,可以复用
62+- 需要处理 Gemini "shell page" 和 "app page" 的区别
63+- `BUG-028`(Gemini shell final-message)已经修复,相关经验可参考
64+
65+## 验收标准
66+
67+- `@browser.gemini` 的 baa 指令能通过 `browser.proxy_delivery` 稳定执行
68+- 插件刚启动后第一条 Gemini delivery 不需要等待"捕获真实请求"
69+- Gemini 新对话和已有对话都能正确 proxy
70+- 不影响现有 ChatGPT/Claude 路径
71+
72+## 执行记录
73+
74+> 以下内容由执行任务的 AI 填写,创建任务时留空。
75+
76+### 开始执行
77+
78+- 执行者:
79+- 开始时间:
80+- 状态变更:`待开始` → `进行中`
81+
82+### 完成摘要
83+
84+- 完成时间:
85+- 状态变更:`进行中` → `已完成`
86+- 修改了哪些文件:
87+- 核心实现思路:
88+- 跑了哪些测试:
89+
90+### 执行过程中遇到的问题
91+
92+- 
93+
94+### 剩余风险
95+
96+- 
A tasks/T-S068.md
+98, -0
 1@@ -0,0 +1,98 @@
 2+# Task T-S068:ChatGPT proxy send 冷启动降级保护
 3+
 4+## 状态
 5+
 6+- 当前状态:`待开始`
 7+- 规模预估:`S`
 8+- 依赖任务:无
 9+- 建议执行者:`Codex`
10+
11+## 直接给对话的提示词
12+
13+读 `/Users/george/code/baa-conductor/tasks/T-S068.md` 任务文档,完成开发任务。
14+
15+如需补背景,再读:
16+
17+- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/renewal/dispatcher.ts`
18+- `/Users/george/code/baa-conductor/plugins/baa-firefox/delivery-adapters.js`
19+
20+## 当前基线
21+
22+- 仓库:`/Users/george/code/baa-conductor`
23+- 分支基线:`main`
24+
25+## 分支与 worktree(强制)
26+
27+- 分支名:`feat/chatgpt-cold-start-protection`
28+- worktree 路径:`/Users/george/code/baa-conductor-chatgpt-cold-start-protection`
29+
30+开工步骤:
31+
32+1. `cd /Users/george/code/baa-conductor`
33+2. `git worktree add ../baa-conductor-chatgpt-cold-start-protection -b feat/chatgpt-cold-start-protection main`
34+3. `cd ../baa-conductor-chatgpt-cold-start-protection`
35+
36+## 风险描述
37+
38+ChatGPT proxy send 依赖最近捕获的真实发送模板(请求头、cookie、conversation 上下文)。当插件刚重载或浏览器刚启动时,如果还没有观察到任何 ChatGPT 真实发送请求,proxy delivery 会静默失败或退回同页 DOM fallback。
39+
40+对于续命场景,这意味着 conductor 重启 + 插件重载后,第一批续命 job 可能全部走 DOM fallback 或直接失败。
41+
42+## 目标
43+
44+为 ChatGPT proxy send 增加冷启动保护,确保插件重载后能尽快恢复到 proxy delivery 能力。
45+
46+## 范围
47+
48+- 分析 ChatGPT proxy send 模板的最小依赖集(哪些字段必须从真实请求捕获,哪些可以预置)
49+- 实现以下至少一种冷启动缓解策略:
50+  - 策略 A:插件在 WS 连接建立后主动触发一次轻量请求(如查询 conversation list),预热模板缓存
51+  - 策略 B:将最近捕获的模板持久化到 `localStorage` 或 conductor 侧,重载后恢复
52+  - 策略 C:在 dispatcher 侧检测到模板缺失时延迟 retry 而不是立即失败,等待插件预热
53+- 在 dispatcher 日志中明确标记"冷启动期间的 delivery 失败"和"模板预热完成"事件
54+
55+## 路径约束
56+
57+- 不修改 ChatGPT 网站的请求协议行为
58+- 不增加对 ChatGPT API 的额外调用(避免触发风控)
59+- 预热请求如果有,必须是只读性质(GET/list),不能发送消息
60+
61+## 需要特别注意
62+
63+- ChatGPT 的请求模板包含 CSRF token、auth header、conversation context,部分字段有时效性
64+- 如果选择持久化模板,需要考虑 token 过期后的自动失效机制
65+- DOM fallback 不是完全不可用,只是稳定性和速度不如 proxy delivery
66+- `BUG-029`(ChatGPT SSE abort)和插件重载刷新(`T-BUG-031`)的修复经验可参考
67+
68+## 验收标准
69+
70+- 插件重载后 30 秒内恢复 ChatGPT proxy delivery 能力
71+- 冷启动期间的续命 job 不会直接标记 failed,而是进入 retry 等待预热
72+- 日志中可区分冷启动 fallback 和正常 proxy failure
73+- 不影响已经预热完成后的正常 delivery 路径
74+
75+## 执行记录
76+
77+> 以下内容由执行任务的 AI 填写,创建任务时留空。
78+
79+### 开始执行
80+
81+- 执行者:
82+- 开始时间:
83+- 状态变更:`待开始` → `进行中`
84+
85+### 完成摘要
86+
87+- 完成时间:
88+- 状态变更:`进行中` → `已完成`
89+- 修改了哪些文件:
90+- 核心实现思路:
91+- 跑了哪些测试:
92+
93+### 执行过程中遇到的问题
94+
95+- 
96+
97+### 剩余风险
98+
99+- 
A tasks/T-S069.md
+106, -0
  1@@ -0,0 +1,106 @@
  2+# Task T-S069:proxy_delivery 成功语义增强 — 补齐下游回复确认
  3+
  4+## 状态
  5+
  6+- 当前状态:`待开始`
  7+- 规模预估:`L`
  8+- 依赖任务:`T-S060`
  9+- 建议执行者:`Claude / Codex`
 10+
 11+## 直接给对话的提示词
 12+
 13+读 `/Users/george/code/baa-conductor/tasks/T-S069.md` 任务文档,完成开发任务。
 14+
 15+如需补背景,再读:
 16+
 17+- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/renewal/dispatcher.ts`
 18+- `/Users/george/code/baa-conductor/plugins/baa-firefox/delivery-adapters.js`
 19+- `/Users/george/code/baa-conductor/plans/AUTOMATION_ARBITRATION_REQUIREMENTS.md`
 20+
 21+## 当前基线
 22+
 23+- 仓库:`/Users/george/code/baa-conductor`
 24+- 分支基线:`main`
 25+
 26+## 分支与 worktree(强制)
 27+
 28+- 分支名:`feat/delivery-ack-confirmation`
 29+- worktree 路径:`/Users/george/code/baa-conductor-delivery-ack-confirmation`
 30+
 31+开工步骤:
 32+
 33+1. `cd /Users/george/code/baa-conductor`
 34+2. `git worktree add ../baa-conductor-delivery-ack-confirmation -b feat/delivery-ack-confirmation main`
 35+3. `cd ../baa-conductor-delivery-ack-confirmation`
 36+
 37+## 风险描述
 38+
 39+当前 `proxy_delivery` 的成功语义是"请求已派发到目标页面上下文",不是"下游 AI 已完整回复"。这意味着:
 40+
 41+- dispatcher 标记 renewal job 为 `done` 时,实际上只确认了请求发出去了
 42+- 如果下游 AI 拒绝了请求(如 rate limit 429、网络超时、session 过期),conductor 不知道
 43+- renewal 的 cooldownUntil 已经设置,但实际续命可能没有成功
 44+- 对于 baa 指令执行,回送结果可能在 proxy 层面"成功"但实际 AI 没有响应
 45+
 46+## 目标
 47+
 48+为 proxy_delivery 补齐下游回复确认机制,使 conductor 能区分"请求已发出"和"下游已响应"。
 49+
 50+## 范围
 51+
 52+- 定义增强后的 delivery 成功语义层级:
 53+  - Level 0:请求已派发(当前行为)
 54+  - Level 1:下游返回了 HTTP 200(proxy 层面确认)
 55+  - Level 2:下游开始了 SSE 流(AI 开始回复)
 56+  - Level 3:下游 SSE 流正常结束(AI 完整回复,即触发了新的 final-message)
 57+- 首版至少实现 Level 1(HTTP 状态码回传)
 58+- 在 dispatcher 中根据回传的状态码决定 job 的最终状态(200 → done,429/5xx → retry)
 59+- 在插件侧补齐 proxy_delivery 的 HTTP 状态码回传到 conductor
 60+
 61+## 路径约束
 62+
 63+- 不要求首版实现 Level 2/3,但数据模型要为后续扩展预留空间
 64+- 不改变现有 proxy_delivery 的请求派发逻辑,只在结果回传上增强
 65+- 状态码回传必须是异步的,不能阻塞 proxy_delivery 的请求派发
 66+
 67+## 需要特别注意
 68+
 69+- ChatGPT 的 proxy delivery 返回的是 SSE 流,需要等到流开始或流结束才能判断成功
 70+- 等流结束可能需要 30s+ — 首版不建议等,只判断 HTTP 状态码即可
 71+- Gemini 的 proxy delivery 结构不同(form data + 非标准 SSE),需要独立处理
 72+- Level 3 实际上就是等下一条 final-message 回来 — 这可以复用现有 final-message 链路,不需要在 proxy 里等
 73+- 如果首版只做 Level 1,job 的 done 语义从"已派发"升级为"下游已接受",这是一个有意义的增强
 74+
 75+## 验收标准
 76+
 77+- proxy_delivery 结果回传中包含下游 HTTP 状态码
 78+- dispatcher 能根据状态码区分成功(200)和失败(429/5xx)
 79+- 429/5xx 的 job 进入 retry 而不是 done
 80+- 不影响现有 proxy_delivery 的请求派发速度
 81+- 日志中记录下游状态码
 82+
 83+## 执行记录
 84+
 85+> 以下内容由执行任务的 AI 填写,创建任务时留空。
 86+
 87+### 开始执行
 88+
 89+- 执行者:
 90+- 开始时间:
 91+- 状态变更:`待开始` → `进行中`
 92+
 93+### 完成摘要
 94+
 95+- 完成时间:
 96+- 状态变更:`进行中` → `已完成`
 97+- 修改了哪些文件:
 98+- 核心实现思路:
 99+- 跑了哪些测试:
100+
101+### 执行过程中遇到的问题
102+
103+- 
104+
105+### 剩余风险
106+
107+-