- 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
+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+-
+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+-
+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+-
+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+-