- commit
- 6516c64
- parent
- 978aa4c
- author
- im_wower
- date
- 2026-03-28 16:18:48 +0800 CST
chore: archive completed proxy delivery tasks
14 files changed,
+649,
-62
+2,
-2
1@@ -13,8 +13,6 @@ bugs/
2
3 ## 待修复
4
5-- `BUG-024`:[`BUG-024-chatgpt-final-message-stale-identity.md`](./BUG-024-chatgpt-final-message-stale-identity.md)
6-- `BUG-025`:[`BUG-025-chatgpt-delivery-targets-shell-page.md`](./BUG-025-chatgpt-delivery-targets-shell-page.md)
7 - `OPT-002`:[`OPT-002-executor-timeout.md`](./OPT-002-executor-timeout.md)
8 - `OPT-003`:[`OPT-003-policy-configurable.md`](./OPT-003-policy-configurable.md)
9 - `OPT-004`:[`OPT-004-final-message-claude-sse-fallback.md`](./OPT-004-final-message-claude-sse-fallback.md)
10@@ -41,6 +39,8 @@ bugs/
11 | BUG-021 | FIXED | buffered SSE full_text 只保留文本 |
12 | BUG-022 | FIXED | Claude final-message relay 已补齐 |
13 | BUG-023 | FIXED | Claude live tab 的 final-message 捕获与重注入已恢复 |
14+| BUG-024 | FIXED | ChatGPT stale final-message replay 已被抑制 |
15+| BUG-025 | FIXED | delivery 已优先路由到业务页,不再默认落到 shell 页 |
16 | MISSING-001 | FIXED | 执行结果已经接到 AI 对话 delivery 主链 |
17 | MISSING-002 | FIXED | 插件侧 delivery plan 执行器已落地 |
18 | MISSING-003 | FIXED | Phase 1 已补齐 browser.claude target |
1@@ -0,0 +1,42 @@
2+# BUG-024: ChatGPT 新对话 final_message 仍复用旧 identity,被 conductor 判重
3+
4+> 提交者:用户实测 + 本地日志核对
5+> 日期:2026-03-28
6+
7+## 现象
8+
9+用户已经在 ChatGPT 新对话里拿到新的 assistant 回复,但 conductor 最新一条 ingest 仍然是:
10+
11+- `status = duplicate_message`
12+- `assistant_message_id = 6b5fb596-902c-4eab-b58e-b49879bdb0f9`
13+- `conversation_id = 69c766dd-f344-839b-a43e-73159aa626e1`
14+
15+而最近一次真正 `executed` 的记录仍停留在更早的一轮旧消息。也就是说,新回复没有作为“新的 final_message”进入 conductor。
16+
17+## 已核对事实
18+
19+1. `conductor` 日志没有新的执行错误
20+2. `handleBrowserFinalMessage()` 只有在 `ingestResult.processResult != null` 时才会进入 delivery;当前没有新的 delivery 记录,说明问题发生在执行前
21+3. `browser.final_message` 的 identity 来自插件侧 `final-message.js`
22+4. ChatGPT 的 final-message 观察仍可能在页面重载、observer reinject 或旧消息 replay 后复用旧 identity
23+
24+## 相关代码
25+
26+- `plugins/baa-firefox/final-message.js`
27+- `plugins/baa-firefox/controller.js`
28+- `apps/conductor-daemon/src/firefox-ws.ts`
29+
30+## 当前判断
31+
32+这是插件侧 ChatGPT final-message 观察 / identity 提取问题,不是 conductor 执行或 delivery 问题。
33+
34+更具体地说,当前至少有两种风险需要排查:
35+
36+- 新 turn 的 `assistant_message_id` / `conversation_id` 提取来源不稳定,仍拿到了旧值
37+- 页面 reload / 脚本 reinject 后,旧消息又被重新 relay,导致 conductor 正确地把它判成重复消息
38+
39+## 严重度
40+
41+**High**
42+
43+这会直接阻断 ChatGPT 的 BAA 新一轮执行。用户看到的是“ChatGPT 已经回复,但 conductor 没有继续工作”。
1@@ -0,0 +1,52 @@
2+# BUG-025: ChatGPT delivery 仍落到 shell 页面或新空白对话,而不是来源对话
3+
4+> 提交者:用户实测 + 代码核对
5+> 日期:2026-03-28
6+
7+## 现象
8+
9+当 ChatGPT 侧触发 BAA 执行后,Firefox 插件可能会:
10+
11+- 重新拉起 `#baa-shell` 页面
12+- 在新的空白 ChatGPT 对话里粘贴 conductor 的执行结果
13+- 把结果发到 shell 页,而不是用户刚才发起指令的来源业务对话
14+
15+用户看到的就是:“当前对话没有收到 conductor 的回复,但 Firefox 新开了一个 ChatGPT 空白对话,并把结果发了进去”。
16+
17+## 已核对事实
18+
19+1. 当前 delivery 仍然走 `browser.inject_message` / `browser.send_message`
20+2. 插件侧 `runDeliveryAction()` 会先 `resolveDeliveryTab(platform)`
21+3. `resolveDeliveryTab("chatgpt")` 的核心行为是 `ensurePlatformTab(platform, ...)`
22+4. 这条链最终只保证 ChatGPT shell tab 存在,并把 delivery 发给该 shell tab
23+
24+## 相关代码
25+
26+- `apps/conductor-daemon/src/artifacts/upload-session.ts`
27+- `apps/conductor-daemon/src/firefox-ws.ts`
28+- `plugins/baa-firefox/controller.js`
29+- `plugins/baa-firefox/delivery-adapters.js`
30+
31+## 当前判断
32+
33+这不是一个 selector 小 bug,而是当前 delivery 架构的结果:
34+
35+- conductor 还不是 delivery 路由的真相源
36+- 插件仍按 `platform -> shell tab` 选择落点
37+- delivery 还是 DOM fallback,而不是真正的 page-context proxy send
38+
39+## 建议处理方式
40+
41+不要继续加码 DOM adapter 试图“猜中正确页面”。这条问题应优先通过主线改造解决:
42+
43+- conductor 记录 conversation / page routing 真相
44+- delivery 改成 browser request proxy
45+- DOM `inject / send` 降级为 fallback
46+
47+对应主线任务:`T-S038`
48+
49+## 严重度
50+
51+**High**
52+
53+这会让 ChatGPT 的回写行为和用户当前上下文脱节,用户很容易误判为“系统没回复”或“回写错会话”。
+3,
-1
1@@ -3,7 +3,7 @@
2 本目录保留 `已关闭` 或 `已修复` 的 `BUG-*`、`FIX-BUG-*`、`MISSING-*` 和 `OPT-*` 文档。
3
4 - 归档时间:`2026-03-28`
5-- 最近新增归档:`BUG-018`、`BUG-019`、`BUG-020`、`BUG-021`、`BUG-022`、`BUG-023`、`MISSING-003`
6+- 最近新增归档:`BUG-018`、`BUG-019`、`BUG-020`、`BUG-021`、`BUG-022`、`BUG-023`、`BUG-024`、`BUG-025`、`MISSING-003`
7
8 最近归档的问题:
9
10@@ -13,4 +13,6 @@
11 - `BUG-021`:buffered SSE `full_text` 现在只保留文本
12 - `BUG-022`:Claude final-message relay 已补齐 SSE 与 buffered 路径
13 - `BUG-023`:Claude live tab 的 final-message 捕获与观察链重注入已恢复
14+- `BUG-024`:ChatGPT stale final-message replay 已被抑制
15+- `BUG-025`:delivery 已优先路由到业务页,不再默认落到 shell 页
16 - `MISSING-003`:Phase 1 已补齐 `browser.claude` target
+4,
-4
1@@ -14,8 +14,8 @@
2 - `browser.claude`
3 - `browser.chatgpt` / `browser.gemini` 目前仍是规划目标,不是当前放开的 Phase 1 target
4 - upload / download / binary delivery 已经废弃,不再是当前插件职责
5-- 当前 delivery 主链仍是 text-only DOM fallback
6-- 下一步主线改造是:由 conductor 持有 conversation / routing 真相,插件只执行 page-context browser request
7+- 当前 delivery 主链已经是 proxy-first,DOM `inject / send` 仅作 fallback
8+- 当前主线已经由 conductor 持有 conversation / routing 真相,插件只执行 page-context browser request
9
10 ---
11
12@@ -355,8 +355,8 @@ function parseParamValue(raw) {
13 当前实际主线请按下面这组事实理解:
14
15 - artifact upload / download 已废弃
16-- 当前 delivery 仍是 text-only fallback
17-- 下一步主线改造见 [`./BAA_BROWSER_PROXY_DELIVERY_REQUIREMENTS.md`](./BAA_BROWSER_PROXY_DELIVERY_REQUIREMENTS.md)
18+- 当前 delivery 已经是 proxy-first,DOM `inject / send` 只保留为 fallback
19+- 代理式 delivery 收口记录见 [`./archive/BAA_BROWSER_PROXY_DELIVERY_REQUIREMENTS.md`](./archive/BAA_BROWSER_PROXY_DELIVERY_REQUIREMENTS.md)
20 - 不要再把本章里的 upload receipt / manifest / 文件上传流程当成当前合同
21
22 ### 8.1 分层策略
1@@ -3,7 +3,7 @@
2 ## 状态
3
4 - `已完成(T-S035,2026-03-28)`
5-- `当前只保留为 DOM fallback 历史方案;主线改造已转到 ./BAA_BROWSER_PROXY_DELIVERY_REQUIREMENTS.md`
6+- `当前只保留为 DOM fallback 历史方案;代理式主链已在 ./archive/BAA_BROWSER_PROXY_DELIVERY_REQUIREMENTS.md 完成`
7 - 优先级:`high`
8 - 记录时间:`2026-03-27`
9
+24,
-18
1@@ -6,7 +6,7 @@
2
3 ## 当前代码基线
4
5-- 当前主分支:`main@499bd69`
6+- 当前主分支:`main`(已包含 `6b819bf`、`6e458f3`、`978aa4c`)
7 - canonical local API:`http://100.71.210.78:4317`
8 - canonical public host:`https://conductor.makefile.so`
9 - 活跃任务文档保留在 `tasks/` 根目录;已完成任务文档归档到 [`../tasks/archive/README.md`](../tasks/archive/README.md)
10@@ -15,14 +15,15 @@
11
12 - Firefox 插件已经具备 page-context `browser/request` 代理能力
13 - ChatGPT / Claude / Gemini 都已经接入 `browser.final_message` raw relay
14+- ChatGPT 新对话 / 新回复的 stale final-message replay 已抑制
15 - conductor 已具备 BAA Phase 1:
16 - `@conductor`
17 - `@system`
18 - `@browser.claude`
19-- delivery 当前仍是 text-only fallback:
20- - conductor 渲染执行结果文本
21- - 通过 `browser.inject_message` / `browser.send_message`
22- - 插件用 DOM adapter 回写
23+- delivery 当前已经是 proxy-first:
24+ - conductor 记录最近观察到的业务页 route
25+ - 优先派发 `browser.proxy_delivery`
26+ - DOM `inject / send` 仅作为 fallback
27 - 页面右下角控制浮层与页面级暂停控制已完成,任务 `T-S037` 已归档
28
29 ## 当前已纠正的文档/代码不一致
30@@ -30,26 +31,28 @@
31 - `T-S037` 之前仍作为 active task 留在根目录,但代码已经合入;现在已归档
32 - `BAA_INSTRUCTION_SYSTEM.md` 之前把 upload / download 写成当前插件职责,也把 `browser.chatgpt` / `browser.gemini` 写成了像是当前已支持 target;现在已补充“当前实现 vs 规划目标”的区分
33 - `BAA_PLUGIN_DELIVERY_HARDENING_REQUIREMENTS.md` 现在只保留为 DOM fallback 历史方案,不再代表当前主线架构方向
34+- `BUG-024` / `BUG-025` 已完成并归档,不再作为 open blocker 挂在 backlog
35
36 ## 当前最高优先级
37
38-1. `T-BUG-020`
39- 修复 ChatGPT 新对话 final-message 仍复用旧 identity,导致新回复被 conductor 判成 `duplicate_message`
40-2. `T-S038`
41- 把 delivery 主链从 DOM `inject / send` 收口成“conductor 持有上下文,插件只执行 browser request”的代理式回写
42-3. `OPT-002`
43+1. `OPT-002`
44 给 executor 加超时保护
45-4. `OPT-006`
46+2. `OPT-006`
47 给 execution persistence 表加自动清理
48+3. `OPT-003`
49+ 让 policy 白名单配置化
50+4. `OPT-004`
51+ 为 Claude final-message 增加更稳的 SSE fallback
52+5. `OPT-005`
53+ 让 normalize / parse 错误进一步隔离,不拖累整批指令
54
55 说明:
56
57-- `BUG-025` 已确认存在,但它本质上是 delivery 架构问题,优先跟随 `T-S038` 一并解决
58-- 其余优化项见 [`../bugs/README.md`](../bugs/README.md)
59+- 当前已没有 open `BUG-*` / `MISSING-*` blocker
60+- 其余 backlog 见 [`../bugs/README.md`](../bugs/README.md)
61
62 ## 当前活跃需求文档
63
64-- [`./BAA_BROWSER_PROXY_DELIVERY_REQUIREMENTS.md`](./BAA_BROWSER_PROXY_DELIVERY_REQUIREMENTS.md)
65 - [`./BAA_INSTRUCTION_SYSTEM.md`](./BAA_INSTRUCTION_SYSTEM.md)
66 - [`./STATUS_SUMMARY.md`](./STATUS_SUMMARY.md)
67
68@@ -60,17 +63,20 @@
69
70 ## 当前主线判断
71
72-现在的关键不是“再补一个 DOM selector”,而是统一浏览器主链:
73+现在浏览器主链的关键收口已经完成:
74
75 - 入站:继续保留 `browser.final_message`
76 - 真相源:由 conductor 记录 conversation / request / routing
77-- 出站:优先改成 browser request proxy
78+- 出站:优先走 browser request proxy
79 - DOM `inject / send`:降为 fallback
80
81 ## 当前仍需关注
82
83 - 风控状态当前仍是进程内内存态;`conductor` 重启后,限流、退避和熔断计数会重置
84 - `Gemini` 当前仍不是 `/v1/browser/request` 的正式支持面,正式 browser target 仍只有 `browser.claude`
85-- ChatGPT final-message 仍存在真实页面 identity 复用问题,见 [`../bugs/BUG-024-chatgpt-final-message-stale-identity.md`](../bugs/BUG-024-chatgpt-final-message-stale-identity.md)
86-- ChatGPT 当前 delivery 仍可能落到 shell 页,见 [`../bugs/BUG-025-chatgpt-delivery-targets-shell-page.md`](../bugs/BUG-025-chatgpt-delivery-targets-shell-page.md)
87+- ChatGPT proxy send 仍依赖最近捕获的真实发送模板;如果 controller 刚重载且还没观察到真实发送,会退回同页 DOM fallback
88+- Claude 的 `organizationId` 当前仍依赖最近观测到的 org 上下文,不是完整的多页多 org 精确映射
89+- `proxy_delivery` 当前的成功语义是“请求已派发到目标页面上下文”,不是“下游 AI 已完整回复”
90+- ChatGPT root message / mapping 结构如果后续变化,final-message 提取启发式仍需跟进
91+- recent relay cache 是有限窗口;极老 replay 超出窗口后,仍会落回 conductor dedupe
92 - `status-api` 继续保留为显式 opt-in 兼容层,不是当前删除重点
1@@ -0,0 +1,62 @@
2+# BAA Browser Proxy Delivery 需求
3+
4+## 状态
5+
6+- `已完成(T-S038,2026-03-28)`
7+- 优先级:`high`
8+- 记录时间:`2026-03-28`
9+
10+## 关联文档
11+
12+- [BAA_INSTRUCTION_SYSTEM.md](../BAA_INSTRUCTION_SYSTEM.md)
13+- [STATUS_SUMMARY.md](../STATUS_SUMMARY.md)
14+- [plugins/baa-firefox/README.md](../../plugins/baa-firefox/README.md)
15+- [BUG-025-chatgpt-delivery-targets-shell-page.md](../../bugs/archive/BUG-025-chatgpt-delivery-targets-shell-page.md)
16+
17+## 背景
18+
19+当前代码已经同时存在两条浏览器能力路径:
20+
21+- 正式 `browser/request` 代理路径:由 conductor 发起,插件在 page context 里带真实登录态执行请求
22+- 旧 delivery fallback:conductor 生成文本结果,插件再用 DOM adapter 注入输入框并点击发送
23+
24+这导致当前 delivery 主链存在结构性问题:
25+
26+- conductor 不是 delivery routing 的唯一真相源
27+- 插件仍按 `platform -> shell tab` 决定结果落点
28+- ChatGPT 结果仍可能落到 shell 页或新空白对话,而不是来源业务对话
29+
30+## 核心结论
31+
32+- conductor 应该成为 conversation / page routing / audit 的真相源
33+- 插件只负责在正确页面上下文里执行真实请求
34+- text-only 结果回写的正式主链应改为 browser request proxy
35+- DOM `inject / send` 只保留为 fallback,不再作为默认主路径
36+
37+## 范围
38+
39+- 定义 conductor 侧最小 conversation / page routing 状态
40+- 为 delivery 建立正式 proxy send contract
41+- 首批至少覆盖 `ChatGPT` 与 `Claude`
42+- browser smoke、service-side test 和读面回写
43+
44+## 当前明确不要求
45+
46+- 不恢复 upload / download / binary delivery
47+- 不扩成多客户端、多轮 orchestrator
48+- 不把 `browser.chatgpt` / `browser.gemini` 一次性扩成完整 Phase 1 target 面
49+- 不做跨节点任务编排
50+
51+## 验收条件
52+
53+- 对已转换平台,delivery 主路径不再依赖输入框选择器和发送按钮
54+- ChatGPT 结果不再默认落到 shell 页或新空白对话
55+- conductor 能解释当前回写目标 conversation / page
56+- fallback 使用条件明确,不会静默退回错误页面
57+- browser smoke 与 service-side test 覆盖成功路径和 fail-closed
58+
59+## 当前预期残余边界
60+
61+- 首版仍然可以只覆盖 `ChatGPT` / `Claude`
62+- 插件页内请求执行仍受平台页面契约变化影响
63+- 在所有平台完成代理回写之前,DOM fallback 仍可能保留一段时间
+2,
-2
1@@ -2,7 +2,7 @@
2
3 本目录只保留 `已完成` 的需求文档。根目录 `plans/` 现在只保留当前活跃需求、总状态摘要和讨论文档。
4
5-- 归档时间:`2026-03-27`
6+- 归档时间:`2026-03-28`
7 - 归档状态:本目录中的需求文档均视为 `已完成`
8
9 ## 已归档需求
10@@ -15,10 +15,10 @@
11 - [`BAA_ARTIFACT_CENTER_REQUIREMENTS.md`](./BAA_ARTIFACT_CENTER_REQUIREMENTS.md):已完成,对应 `T-S032`
12 - [`BAA_EXECUTION_PERSISTENCE_REQUIREMENTS.md`](./BAA_EXECUTION_PERSISTENCE_REQUIREMENTS.md):已完成,对应 `T-S033`
13 - [`BAA_DELIVERY_BRIDGE_REQUIREMENTS.md`](./BAA_DELIVERY_BRIDGE_REQUIREMENTS.md):已完成,对应 `T-S034`
14+- [`BAA_BROWSER_PROXY_DELIVERY_REQUIREMENTS.md`](./BAA_BROWSER_PROXY_DELIVERY_REQUIREMENTS.md):已完成,对应 `T-S038`
15
16 ## 当前仍在根目录的需求文档
17
18-- [`../BAA_BROWSER_PROXY_DELIVERY_REQUIREMENTS.md`](../BAA_BROWSER_PROXY_DELIVERY_REQUIREMENTS.md)
19 - [`../BAA_INSTRUCTION_SYSTEM.md`](../BAA_INSTRUCTION_SYSTEM.md)
20 - [`../STATUS_SUMMARY.md`](../STATUS_SUMMARY.md)
21 - [`../BAA_PLUGIN_DELIVERY_HARDENING_REQUIREMENTS.md`](../BAA_PLUGIN_DELIVERY_HARDENING_REQUIREMENTS.md):已完成,当前只作为 DOM fallback 历史方案
+19,
-30
1@@ -3,7 +3,7 @@
2 ## 当前基线
3
4 - 日期:`2026-03-28`
5-- 主分支基线:`main@499bd69`
6+- 主分支基线:`main`(已包含 `6b819bf`、`6e458f3`、`978aa4c`)
7 - canonical local API:`http://100.71.210.78:4317`
8 - canonical public host:`https://conductor.makefile.so`
9 - 当前活跃任务卡保留在本目录;已完成任务卡已归档到 [`./archive/README.md`](./archive/README.md)
10@@ -14,11 +14,12 @@
11
12 - Firefox 插件已具备页面观察、登录态元数据采集、page-context `browser/request` 代理执行
13 - ChatGPT / Claude / Gemini 都已接入 `browser.final_message` raw relay
14+- ChatGPT 新对话 / 新回复的 stale final-message replay 已抑制,不再默认把新回复判成旧消息 `duplicate_message`
15 - conductor 已具备 BAA Phase 1:`@conductor` / `@system` / `@browser.claude`
16-- delivery 当前仍是 text-only fallback:
17- - conductor 生成执行结果文本
18- - 通过 `browser.inject_message` / `browser.send_message`
19- - 由插件用 DOM adapter 回写到页面
20+- delivery 当前已经是 proxy-first:
21+ - conductor 记录最近观察到的业务页 route 与回写目标
22+ - 优先通过 `browser.proxy_delivery` 在目标页面上下文执行真实请求
23+ - `browser.inject_message` / `browser.send_message` 仅作为 fallback
24 - `T-S037` 对应的页面右下角浮层与页面级暂停控制已经在代码里完成,并已归档
25
26 ## 当前已确认的不一致
27@@ -27,24 +28,18 @@
28
29 - `T-S037` 之前仍挂在根目录作为 active task,但代码已经合入 `main`;现在已归档
30 - `plans/BAA_INSTRUCTION_SYSTEM.md` 之前把 upload / download 写成当前插件职责,也把 `browser.chatgpt` / `browser.gemini` 写得像当前已支持 target;现在已补充“当前实现 vs 规划目标”的区分
31-- 当前真正的架构矛盾不在“有没有 proxy request”,而在“delivery 仍然走 DOM fallback”;这已经单独收口成新任务 [`T-S038.md`](./T-S038.md)
32+- `BUG-024` / `BUG-025` 已经分别随 `6b819bf` 和 `6e458f3` 收口,不再作为 open bug 保留在根目录索引
33
34 ## 当前活跃任务与优先级
35
36-### P0
37-
38-- [`T-BUG-020.md`](./T-BUG-020.md):修复 ChatGPT 新对话 final-message 仍复用旧 message / conversation identity,导致 conductor 把新回复判成 `duplicate_message`
39+当前根目录已没有活跃任务卡;这轮 `T-BUG-020`、`T-S037`、`T-S038` 都已完成并归档。
40
41 ### P1
42
43-- [`T-S038.md`](./T-S038.md):把 delivery 从 DOM `inject / send` 重构为“conductor 持有上下文,插件只执行 page-context browser request”的代理式回写主链
44-
45-### P2
46-
47 - [`../bugs/OPT-002-executor-timeout.md`](../bugs/OPT-002-executor-timeout.md)
48 - [`../bugs/OPT-006-db-table-auto-cleanup.md`](../bugs/OPT-006-db-table-auto-cleanup.md)
49
50-### P3
51+### P2
52
53 - [`../bugs/OPT-003-policy-configurable.md`](../bugs/OPT-003-policy-configurable.md)
54 - [`../bugs/OPT-004-final-message-claude-sse-fallback.md`](../bugs/OPT-004-final-message-claude-sse-fallback.md)
55@@ -52,18 +47,15 @@
56
57 ## 当前 open bug / gap
58
59-- [`../bugs/BUG-024-chatgpt-final-message-stale-identity.md`](../bugs/BUG-024-chatgpt-final-message-stale-identity.md)
60-- [`../bugs/BUG-025-chatgpt-delivery-targets-shell-page.md`](../bugs/BUG-025-chatgpt-delivery-targets-shell-page.md)
61-- 其余优化项见 [`../bugs/README.md`](../bugs/README.md)
62+当前没有 open `BUG-*` 或 `MISSING-*`;剩余 backlog 已全部收口为 `OPT-*` 优化项,见 [`../bugs/README.md`](../bugs/README.md)。
63
64 说明:
65
66-- `BUG-024` 是当前 ChatGPT 端到端闭环的直接 blocker,所以先单独拆 bug 修
67-- `BUG-025` 本质上是 delivery 架构问题,优先通过 [`T-S038.md`](./T-S038.md) 一次性收口,不再继续加码 DOM adapter
68+- `OPT-002` 和 `OPT-006` 现在是最值得继续推进的两项工程稳定性工作
69+- `OPT-003` / `OPT-004` / `OPT-005` 属于次一级优化,不再阻塞当前主线
70
71 ## 当前活跃需求文档
72
73-- [`../plans/BAA_BROWSER_PROXY_DELIVERY_REQUIREMENTS.md`](../plans/BAA_BROWSER_PROXY_DELIVERY_REQUIREMENTS.md)
74 - [`../plans/BAA_INSTRUCTION_SYSTEM.md`](../plans/BAA_INSTRUCTION_SYSTEM.md)
75 - [`../plans/STATUS_SUMMARY.md`](../plans/STATUS_SUMMARY.md)
76
77@@ -74,19 +66,16 @@
78
79 ## 当前主线判断
80
81-现在最值得继续推进的不是再补一个 DOM selector,而是把“浏览器请求代理”与“回写交付”统一起来:
82+这轮主线已经完成两件关键收口:
83
84-- 入站:继续保留 `browser.final_message`
85-- 中控:由 conductor 持有 conversation / request / routing 真相
86-- 出站:优先改成 conductor 下发代理请求,插件只在 page context 执行
87-- DOM `inject / send` 降为 fallback,而不是主链
88+- ChatGPT stale final-message replay 已被抑制
89+- browser delivery 已从默认 shell-page DOM 回写,收口到 proxy-first 的业务页回写链
90
91-## 任务文档约定
92+下一步最值得继续推进的是工程稳定性,而不是再补一个 selector:
93
94-- 任务卡统一使用纯 Markdown 结构,不使用 frontmatter
95-- 每张任务卡都要写清当前基线、必须创建的新分支名、允许修改目录和验收命令
96-- Firefox 插件相关的大任务,优先要求新建 `git worktree`,避免污染当前稳定可用插件
97-- 新任务优先参考 [`task-doc-template.md`](./task-doc-template.md)
98+- executor 超时保护
99+- DB 自动清理
100+- policy / relay / parse 的次级优化
101
102 ## 现在该读什么
103
+2,
-4
1@@ -9,13 +9,11 @@
2
3 - 基础收口:[`T-S001.md`](./T-S001.md)、[`T-S002.md`](./T-S002.md)、[`T-S003.md`](./T-S003.md)、[`T-S004.md`](./T-S004.md)、[`T-S005.md`](./T-S005.md)、[`T-S006.md`](./T-S006.md)、[`T-S007.md`](./T-S007.md)、[`T-S008.md`](./T-S008.md)、[`T-S009.md`](./T-S009.md)、[`T-S010.md`](./T-S010.md)、[`T-S011.md`](./T-S011.md)、[`T-S012.md`](./T-S012.md)、[`T-S013.md`](./T-S013.md)、[`T-S014.md`](./T-S014.md)、[`T-S015.md`](./T-S015.md)、[`T-S016.md`](./T-S016.md)
4 - 浏览器桥接主线:[`T-S017.md`](./T-S017.md)、[`T-S018.md`](./T-S018.md)、[`T-S019.md`](./T-S019.md)、[`T-S020.md`](./T-S020.md)、[`T-S021.md`](./T-S021.md)、[`T-S022.md`](./T-S022.md)、[`T-S023.md`](./T-S023.md)、[`T-S024.md`](./T-S024.md)、[`T-S025.md`](./T-S025.md)、[`T-S026.md`](./T-S026.md)、[`T-S027.md`](./T-S027.md)、[`T-S028.md`](./T-S028.md)
5-- BAA 主线:[`T-S029.md`](./T-S029.md)、[`T-S030.md`](./T-S030.md)、[`T-S031.md`](./T-S031.md)、[`T-S032.md`](./T-S032.md)、[`T-S033.md`](./T-S033.md)、[`T-S034.md`](./T-S034.md)、[`T-S035.md`](./T-S035.md)、[`T-S036.md`](./T-S036.md)
6+- BAA 主线:[`T-S029.md`](./T-S029.md)、[`T-S030.md`](./T-S030.md)、[`T-S031.md`](./T-S031.md)、[`T-S032.md`](./T-S032.md)、[`T-S033.md`](./T-S033.md)、[`T-S034.md`](./T-S034.md)、[`T-S035.md`](./T-S035.md)、[`T-S036.md`](./T-S036.md)、[`T-S038.md`](./T-S038.md)
7 - 页面控制:[`T-S037.md`](./T-S037.md)
8-- 缺陷修复:[`T-BUG-011.md`](./T-BUG-011.md)、[`T-BUG-012.md`](./T-BUG-012.md)、[`T-BUG-014.md`](./T-BUG-014.md)、[`T-BUG-015.md`](./T-BUG-015.md)、[`T-BUG-016.md`](./T-BUG-016.md)、[`T-BUG-017.md`](./T-BUG-017.md)、[`T-BUG-018.md`](./T-BUG-018.md)、[`T-BUG-019.md`](./T-BUG-019.md)、[`T-MISSING-003.md`](./T-MISSING-003.md)
9+- 缺陷修复:[`T-BUG-011.md`](./T-BUG-011.md)、[`T-BUG-012.md`](./T-BUG-012.md)、[`T-BUG-014.md`](./T-BUG-014.md)、[`T-BUG-015.md`](./T-BUG-015.md)、[`T-BUG-016.md`](./T-BUG-016.md)、[`T-BUG-017.md`](./T-BUG-017.md)、[`T-BUG-018.md`](./T-BUG-018.md)、[`T-BUG-019.md`](./T-BUG-019.md)、[`T-BUG-020.md`](./T-BUG-020.md)、[`T-MISSING-003.md`](./T-MISSING-003.md)
10
11 ## 当前仍在根目录的任务卡
12
13 - [`../TASK_OVERVIEW.md`](../TASK_OVERVIEW.md):当前任务总览
14-- [`../T-BUG-020.md`](../T-BUG-020.md):当前最高优先级 ChatGPT final-message bug 修复
15-- [`../T-S038.md`](../T-S038.md):当前主线代理式 delivery 改造
16 - [`../task-doc-template.md`](../task-doc-template.md):新任务模板
+131,
-0
1@@ -0,0 +1,131 @@
2+# Task T-BUG-020:修复 ChatGPT 新对话 final-message 仍复用旧 identity
3+
4+> 已完成并归档:`2026-03-28`
5+
6+## 直接给对话的提示词
7+
8+读 `/Users/george/code/baa-conductor/tasks/archive/T-BUG-020.md` 任务文档,查看已完成任务记录。
9+
10+如需补背景,再读:
11+
12+- `/Users/george/code/baa-conductor/bugs/archive/BUG-024-chatgpt-final-message-stale-identity.md`
13+- `/Users/george/code/baa-conductor/tasks/TASK_OVERVIEW.md`
14+- `/Users/george/code/baa-conductor/plans/BAA_INSTRUCTION_SYSTEM.md`
15+
16+## 当前基线
17+
18+- 仓库:`/Users/george/code/baa-conductor`
19+- 分支基线:`main`
20+- 提交:`499bd69`
21+- 开工要求:必须先从当前 `main` 新建任务分支,再开始开发;禁止直接在 `main` 上修改。功能任务分支名必须以 `feat/` 开头,缺陷任务分支名必须以 `bug/` 开头。
22+- 开发隔离要求:必须使用新的 `git worktree` 开发本任务,禁止直接在当前正在使用的插件工作目录里修改并 reload 扩展,避免影响当前稳定可用的 Firefox 插件。
23+
24+## 必须创建的新分支名
25+
26+- `bug/bug-024-chatgpt-final-message-identity`
27+
28+## 推荐 worktree
29+
30+- 建议新建:`/Users/george/code/baa-conductor-bug-024`
31+- 建议命令:`git worktree add ../baa-conductor-bug-024 -b bug/bug-024-chatgpt-final-message-identity main`
32+
33+## 目标
34+
35+让 ChatGPT 的新对话 / 新回复在真实页面里稳定产出新的 `browser.final_message` identity,不再把新消息上报成旧消息重放,导致 conductor 判成 `duplicate_message`。
36+
37+## 背景
38+
39+当前真实测试里,用户已经在 ChatGPT 新对话里拿到新的 assistant 回复,但 conductor 最新 ingest 仍然显示:
40+
41+- `status = duplicate_message`
42+- `assistant_message_id` 还是旧值
43+- `conversation_id` 还是旧值
44+
45+与此同时,conductor 的 delivery 没有新记录,说明问题发生在 final-message 上报之前或上报时,不是在执行或 delivery 阶段。
46+
47+这张卡的重点不是改 conductor dedupe,而是修正 ChatGPT 页面观察 / 提取 / relay identity。
48+
49+## 涉及仓库
50+
51+- `/Users/george/code/baa-conductor`
52+
53+## 范围
54+
55+- 修复 ChatGPT final-message identity 复用旧 assistant / conversation 的问题
56+- 修复页面重载、脚本 reinject 或旧消息重放导致的 stale relay
57+- 补最小自动化回归
58+
59+## 路径约束
60+
61+优先在 Firefox 插件的 final-message 观察链里解决,不要通过放宽 conductor dedupe 来掩盖问题。必要时才最小改动 `conductor-daemon` 测试或快照读面。
62+
63+## 推荐实现边界
64+
65+建议优先做:
66+
67+- 检查 ChatGPT candidate 提取对 conversationId / assistantMessageId 的来源优先级
68+- 检查 observer reinject / stream state 是否会把旧页面的旧消息再次当成新消息上报
69+- 保持 conductor 现有 dedupe 语义,不要把“旧消息重放”误判为新执行
70+
71+## 允许修改的目录
72+
73+- `/Users/george/code/baa-conductor/plugins/baa-firefox/final-message.js`
74+- `/Users/george/code/baa-conductor/plugins/baa-firefox/controller.js`
75+- `/Users/george/code/baa-conductor/plugins/baa-firefox/page-interceptor.js`
76+- `/Users/george/code/baa-conductor/tests/browser/browser-control-e2e-smoke.test.mjs`
77+- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/index.test.js`
78+
79+## 尽量不要修改
80+
81+- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/instructions/`
82+- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/firefox-ws.ts`
83+- `/Users/george/code/baa-conductor/plugins/baa-firefox/delivery-adapters.js`
84+- `/Users/george/code/baa-conductor/docs/`
85+
86+## 必须完成
87+
88+### 1. 修正新消息 identity
89+
90+- 新的 ChatGPT assistant 回复要生成新的 `assistant_message_id` / `conversation_id` 组合,或至少生成新的 relay identity
91+- 不允许继续把新对话回复上报成旧消息
92+
93+### 2. 修正 stale replay
94+
95+- 页面刷新、扩展 reload、脚本 reinject 后,旧消息不能再次被当成新消息 relay
96+- 但真正的新回复仍然要能被 relay
97+
98+### 3. 补回归
99+
100+- 覆盖 ChatGPT 新 turn 的 final-message identity 更新
101+- 覆盖旧消息 replay 不会错误触发新执行
102+- 保持现有 Claude / Gemini final-message 行为不回归
103+
104+## 需要特别注意
105+
106+- 不要通过关闭 conductor dedupe 来“修复”这个问题
107+- 不要把这张卡扩成 delivery 架构重构;delivery 改造留给 `T-S038`
108+- 不要回退已经修好的 Claude live-tab / final-message 观察链
109+
110+## 验收标准
111+
112+- 新的 ChatGPT 回复进入 conductor 时,不再被判成旧消息 `duplicate_message`
113+- `instruction_ingest.last_execute` 能出现新的 assistant message identity
114+- ChatGPT、Claude、Gemini 现有 final-message 测试不回归
115+
116+## 推荐验证命令
117+
118+- `node --check /Users/george/code/baa-conductor/plugins/baa-firefox/final-message.js`
119+- `node --check /Users/george/code/baa-conductor/plugins/baa-firefox/controller.js`
120+- `node --test /Users/george/code/baa-conductor/tests/browser/browser-control-e2e-smoke.test.mjs`
121+- `node --test /Users/george/code/baa-conductor/apps/conductor-daemon/src/index.test.js`
122+- `git diff --check`
123+
124+## 交付要求
125+
126+完成后请说明:
127+
128+- 修改了哪些文件
129+- identity 复用的根因是什么
130+- 新的 dedupe / relay 判断是怎么做的
131+- 跑了哪些测试
132+- 还有哪些剩余风险
+148,
-0
1@@ -0,0 +1,148 @@
2+# Task T-S037:恢复 AI 页面右下角控制浮层,并支持页面级暂停 BAA 控制
3+
4+> 已完成并归档:`2026-03-28`
5+
6+## 直接给对话的提示词
7+
8+读 `/Users/george/code/baa-conductor/tasks/archive/T-S037.md` 任务文档,查看已完成任务记录。
9+
10+如需补背景,再读:
11+
12+- `/Users/george/code/baa-conductor/plugins/baa-firefox/README.md`
13+- `/Users/george/code/baa-conductor/tasks/TASK_OVERVIEW.md`
14+- `/Users/george/code/baa-conductor/plans/BAA_INSTRUCTION_SYSTEM.md`
15+
16+## 当前基线
17+
18+- 仓库:`/Users/george/code/baa-conductor`
19+- 分支基线:`main`
20+- 提交:`7dc34ad`
21+- 开工要求:必须先从当前 `main` 新建任务分支,再开始开发;禁止直接在 `main` 上修改。功能任务分支名必须以 `feat/` 开头,缺陷任务分支名必须以 `bug/` 开头。
22+- 开发隔离要求:必须使用新的 `git worktree` 开发本任务,禁止直接在当前正在使用的插件工作目录里修改并 reload 扩展,避免影响当前稳定可用的 Firefox 插件。
23+
24+## 必须创建的新分支名
25+
26+- `feat/page-level-baa-control-overlay`
27+
28+## 推荐 worktree
29+
30+- 建议新建:`/Users/george/code/baa-conductor-ts037`
31+- 建议命令:`git worktree add ../baa-conductor-ts037 -b feat/page-level-baa-control-overlay main`
32+
33+## 目标
34+
35+把 AI 网页右下角的控制浮层正式恢复回来,并支持“仅暂停当前页面 / 当前对话的 BAA 控制”,避免死循环时只能做全局暂停。
36+
37+## 背景
38+
39+当前仓库已经补了一个临时止损方案:在支持的 AI 网页右下角注入全局 `pause / resume / drain` 浮层。但这只是全局控制,不是用户真正需要的“只暂停当前页面 / 当前对话”。
40+
41+现状问题:
42+
43+- 当前页面没有正式的页面级 BAA 控制开关
44+- 一旦出现循环,用户只能全局 `pause`
45+- `browser.final_message` 和 delivery 仍然按平台主链工作,无法只对某一个页面停用
46+
47+这张卡的目标不是继续扩大全局控制,而是把页面级 stop switch 正式落地。
48+
49+## 涉及仓库
50+
51+- `/Users/george/code/baa-conductor`
52+
53+## 范围
54+
55+- 恢复 AI 页面右下角控制浮层为正式能力,而不是临时 stopgap
56+- 增加页面级 / tab 级 BAA 暂停状态
57+- 让被暂停页面不再继续参与 `browser.final_message` 上报和 delivery 回写
58+- 补最小自动化回归
59+
60+## 路径约束
61+
62+优先在 Firefox 插件运行时层完成,不要把这张卡扩成完整多页面会话框架重构。只有在确实需要 conductor 读面暴露时,才最小改动 `apps/conductor-daemon/src/`。
63+
64+## 推荐实现边界
65+
66+建议优先做:
67+
68+- 页面浮层状态以 `tabId + platform` 为主键;如果页面里已经能稳定取到 `conversationId`,可以作为补充字段保留
69+- 页面级暂停后,至少阻断该页面的 `browser.final_message`
70+- 如果该页面被标记为暂停,delivery 也不要继续往该页面注入 / 发送
71+- 在 controller 或 `/v1/browser` 读面里保留最小可观察状态,便于排查“为什么这个页面没有继续执行”
72+
73+## 允许修改的目录
74+
75+- `/Users/george/code/baa-conductor/plugins/baa-firefox/content-script.js`
76+- `/Users/george/code/baa-conductor/plugins/baa-firefox/controller.js`
77+- `/Users/george/code/baa-conductor/plugins/baa-firefox/page-interceptor.js`
78+- `/Users/george/code/baa-conductor/plugins/baa-firefox/final-message.js`
79+- `/Users/george/code/baa-conductor/plugins/baa-firefox/background.js`
80+- `/Users/george/code/baa-conductor/tests/browser/browser-control-e2e-smoke.test.mjs`
81+- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/firefox-ws.ts`
82+- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/browser-types.ts`
83+- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/local-api.ts`
84+
85+## 尽量不要修改
86+
87+- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/instructions/`
88+- `/Users/george/code/baa-conductor/plugins/baa-firefox/delivery-adapters.js`
89+- `/Users/george/code/baa-conductor/docs/`
90+
91+## 必须完成
92+
93+### 1. 恢复正式页面浮层
94+
95+- 在 Claude / ChatGPT / Gemini 页面右下角显示 BAA 控制浮层
96+- 浮层至少要能显示当前页面是否被暂停
97+- 不要再只依赖 `controller.html` 做控制入口
98+
99+### 2. 支持页面级暂停
100+
101+- 用户可以只暂停当前页面 / 当前 tab 的 BAA 控制
102+- 被暂停页面的 `browser.final_message` 不再继续上报给 conductor
103+- 恢复后该页面能继续进入正常观察链
104+
105+### 3. 收口 delivery 行为
106+
107+- 被暂停页面不应继续接收自动 delivery 回写
108+- 其他未暂停页面和全局控制语义不能被破坏
109+- 临时全局浮层可以保留,但不能和页面级状态冲突
110+
111+### 4. 补回归
112+
113+- 覆盖页面级暂停后 `browser.final_message` 被抑制
114+- 覆盖恢复后观察链重新生效
115+- 覆盖现有全局 `pause / resume / drain` 语义不回归
116+
117+## 需要特别注意
118+
119+- 不要把这张卡扩成完整 conversation manager 或多 tab orchestration 重构
120+- 不要破坏当前 shell tab、desired / actual / drift 语义
121+- 不要回退已经修好的 Claude / ChatGPT / Gemini final-message 观察链
122+- 页面级暂停和全局 `system pause` 要能区分,不能混成一个状态
123+
124+## 验收标准
125+
126+- 在支持的 AI 网页里能看到右下角 BAA 控制浮层
127+- 用户可以只暂停当前页面,而不是只能全局暂停
128+- 被暂停页面不会继续触发 `browser.final_message -> conductor -> delivery`
129+- 恢复后该页面重新参与主链
130+- 现有 browser smoke 通过
131+
132+## 推荐验证命令
133+
134+- `node --check /Users/george/code/baa-conductor/plugins/baa-firefox/content-script.js`
135+- `node --check /Users/george/code/baa-conductor/plugins/baa-firefox/controller.js`
136+- `node --check /Users/george/code/baa-conductor/plugins/baa-firefox/page-interceptor.js`
137+- `node --check /Users/george/code/baa-conductor/plugins/baa-firefox/final-message.js`
138+- `node --test /Users/george/code/baa-conductor/tests/browser/browser-control-e2e-smoke.test.mjs`
139+- `git diff --check`
140+
141+## 交付要求
142+
143+完成后请说明:
144+
145+- 修改了哪些文件
146+- 页面级暂停状态是怎么建模的
147+- `browser.final_message` 和 delivery 各自如何尊重该状态
148+- 跑了哪些测试
149+- 还有哪些剩余风险
+157,
-0
1@@ -0,0 +1,157 @@
2+# Task T-S038:用 browser request 代理替换 DOM delivery,由 conductor 持有会话上下文
3+
4+> 已完成并归档:`2026-03-28`
5+
6+## 直接给对话的提示词
7+
8+读 `/Users/george/code/baa-conductor/tasks/archive/T-S038.md` 任务文档,查看已完成任务记录。
9+
10+如需补背景,再读:
11+
12+- `/Users/george/code/baa-conductor/plans/archive/BAA_BROWSER_PROXY_DELIVERY_REQUIREMENTS.md`
13+- `/Users/george/code/baa-conductor/plans/BAA_INSTRUCTION_SYSTEM.md`
14+- `/Users/george/code/baa-conductor/plugins/baa-firefox/README.md`
15+- `/Users/george/code/baa-conductor/tasks/TASK_OVERVIEW.md`
16+
17+## 当前基线
18+
19+- 仓库:`/Users/george/code/baa-conductor`
20+- 分支基线:`main`
21+- 提交:`499bd69`
22+- 开工要求:必须先从当前 `main` 新建任务分支,再开始开发;禁止直接在 `main` 上修改。功能任务分支名必须以 `feat/` 开头,缺陷任务分支名必须以 `bug/` 开头。
23+- 开发隔离要求:必须使用新的 `git worktree` 开发本任务,禁止直接在当前正在使用的插件工作目录里修改并 reload 扩展,避免影响当前稳定可用的 Firefox 插件。
24+
25+## 必须创建的新分支名
26+
27+- `feat/browser-request-proxy-delivery`
28+
29+## 推荐 worktree
30+
31+- 建议新建:`/Users/george/code/baa-conductor-ts038`
32+- 建议命令:`git worktree add ../baa-conductor-ts038 -b feat/browser-request-proxy-delivery main`
33+
34+## 目标
35+
36+把当前“conductor 生成文本结果 -> 插件 DOM 注入输入框 -> 点击发送”的 delivery 主链,重构为“conductor 持有对话上下文 -> 插件只在页面上下文执行 browser request”的代理式回写主链。
37+
38+## 背景
39+
40+当前代码已经具备两条不同层级的浏览器能力:
41+
42+- 已有正式 `POST /v1/browser/request`,可以通过插件在页面上下文中带真实登录态执行请求
43+- 但 BAA 执行结果的 delivery 仍走 `browser.inject_message` / `browser.send_message`,本质上还是 DOM 自动化
44+
45+这带来两个直接问题:
46+
47+- conductor 不是真正的 delivery 路由真相源,落点仍由插件 shell tab 决定
48+- ChatGPT 回写仍可能落到 Firefox shell 页或新空白对话,而不是来源业务对话
49+
50+用户当前希望的模型是:
51+
52+- conductor 记录上下文、conversationId、requestId、路由与审计
53+- 插件不再自己决定业务回写落点
54+- 插件只负责“在对应页面上下文里执行真实请求”
55+
56+## 涉及仓库
57+
58+- `/Users/george/code/baa-conductor`
59+
60+## 范围
61+
62+- 把 delivery 主链从 DOM `inject / send` 重构到 browser request proxy
63+- 让 conductor 成为 conversation / delivery routing 的真相源
64+- 首批至少收口 `ChatGPT` 与 `Claude` 的 text-only 回写
65+- 保留最小 fallback,但不再把 DOM delivery 当主链
66+- 补服务端与 browser smoke 回归
67+
68+## 路径约束
69+
70+优先在 `conductor-daemon` 的 browser bridge / local API / delivery bridge 和 Firefox 插件 controller / page-interceptor 层完成。不要把这张卡扩成完整多客户端、多节点编排,也不要顺手改 instruction parser。
71+
72+## 推荐实现边界
73+
74+建议优先做:
75+
76+- 在 conductor 侧建立最小 conversation / page routing 状态,而不是继续让插件按 shell tab 猜落点
77+- 为 delivery 定义正式的 proxy send contract,优先复用现有 `/v1/browser/request`
78+- 先让 `ChatGPT` 与 `Claude` 走新的代理回写主链
79+- 当前 DOM `inject / send` 只保留为 fallback,不再作为默认成功路径
80+
81+## 允许修改的目录
82+
83+- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/artifacts/upload-session.ts`
84+- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/firefox-ws.ts`
85+- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/firefox-bridge.ts`
86+- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/local-api.ts`
87+- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/browser-types.ts`
88+- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/index.test.js`
89+- `/Users/george/code/baa-conductor/plugins/baa-firefox/controller.js`
90+- `/Users/george/code/baa-conductor/plugins/baa-firefox/page-interceptor.js`
91+- `/Users/george/code/baa-conductor/plugins/baa-firefox/final-message.js`
92+- `/Users/george/code/baa-conductor/tests/browser/browser-control-e2e-smoke.test.mjs`
93+
94+## 尽量不要修改
95+
96+- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/instructions/`
97+- `/Users/george/code/baa-conductor/packages/db/`
98+- `/Users/george/code/baa-conductor/plugins/baa-firefox/delivery-adapters.js`
99+- `/Users/george/code/baa-conductor/docs/baa-instruction-system-v5/`
100+
101+## 必须完成
102+
103+### 1. 收口 conductor 侧上下文真相
104+
105+- conductor 需要有最小可解释的 conversation / page routing 状态
106+- delivery 不再只靠 `platform -> shell tab` 推断落点
107+- 读面至少要能解释“当前回写目标是谁”
108+
109+### 2. 建立代理式 delivery 主链
110+
111+- BAA 执行结果的主路径改成 browser request proxy,而不是 DOM 注入输入框
112+- 插件只负责在正确页面上下文发真实请求
113+- `ChatGPT` 与 `Claude` 至少要有一条正式成功路径
114+
115+### 3. 保留最小 fallback
116+
117+- 当前 DOM `inject / send` 可以保留为 fallback
118+- 但不能继续作为默认主链
119+- fail-closed 行为要明确,不能静默退回错页面
120+
121+### 4. 补回归
122+
123+- 覆盖 delivery 不再默认落到 shell 页
124+- 覆盖代理回写成功路径
125+- 覆盖回写目标缺失或上下文不一致时的 fail-closed
126+
127+## 需要特别注意
128+
129+- 不要恢复 upload / download / binary delivery
130+- 不要把这张卡扩成完整 conversation manager 平台框架
131+- 不要破坏现有 `browser.final_message -> instruction_ingest` 主链
132+- 如果必须保留 fallback,要明确哪个平台、什么条件下才允许走 DOM delivery
133+
134+## 验收标准
135+
136+- `ChatGPT` 的执行结果不再默认回写到 shell 页或新空白对话
137+- conductor 能解释并记录当前 delivery 的目标 conversation / page
138+- 对已转换平台,主路径不再依赖输入框选择器和发送按钮
139+- browser smoke 与 service-side 测试通过
140+
141+## 推荐验证命令
142+
143+- `./node_modules/.bin/tsc -p /Users/george/code/baa-conductor/apps/conductor-daemon/tsconfig.json`
144+- `node --check /Users/george/code/baa-conductor/plugins/baa-firefox/controller.js`
145+- `node --check /Users/george/code/baa-conductor/plugins/baa-firefox/page-interceptor.js`
146+- `node --test /Users/george/code/baa-conductor/apps/conductor-daemon/src/index.test.js /Users/george/code/baa-conductor/tests/browser/browser-control-e2e-smoke.test.mjs`
147+- `git diff --check`
148+
149+## 交付要求
150+
151+完成后请说明:
152+
153+- 修改了哪些文件
154+- conductor 侧上下文是怎么建模的
155+- 新的 proxy delivery 主链是如何工作的
156+- 哪些平台已经从 DOM fallback 转到正式代理回写
157+- 跑了哪些测试
158+- 还有哪些剩余风险