baa-conductor


baa-conductor / tasks / archive
im_wower  ·  2026-03-28

T-S026.md

  1# Task T-S026:真实 Firefox 手工 Smoke 与验收记录
  2
  3## 直接给对话的提示词
  4
  5`/Users/george/code/baa-conductor/tasks/archive/T-S026.md` 任务文档,完成开发任务。
  6
  7如需补背景,再读:
  8
  9- `/Users/george/code/baa-conductor/tasks/archive/T-S025.md`
 10- `/Users/george/code/baa-conductor/docs/api/firefox-local-ws.md`
 11- `/Users/george/code/baa-conductor/docs/api/control-interfaces.md`
 12- `/Users/george/code/baa-conductor/plugins/baa-firefox/README.md`
 13- `/Users/george/code/baa-conductor/plans/STATUS_SUMMARY.md`
 14
 15## 当前基线
 16
 17- 仓库:`/Users/george/code/baa-conductor`
 18- 分支:`main`
 19- 提交:`a2b1055`
 20- 开工要求:不要从其他任务分支切出;如需新分支,从当前 `main` 新切
 21
 22## 当前状态
 23
 24- `已完成(2026-03-27)`
 25- `2026-03-27`:已在真实 `Firefox.app` 环境完成 `plugin_status`、`tab_open`、`tab_restore`、`ws_reconnect` 和“扩展重载后自动恢复”手工 smoke。
 26- `2026-03-27`:场景 D 额外补做了 `disconnect_ms=3000`、`repeat_count=3`、`repeat_interval_ms=500` 的多轮 WS 重连稳定性验证;3 轮断开重连后,`plugin_status` 恢复到 `actual_count=3`、`desired_count=3`、`drift_count=0`。
 27- `2026-03-27`:本轮未发现需要新开卡的 Firefox 手工验收缺陷;当前主线剩余任务已切换到 `T-S035``T-S036` 28
 29## 建议分支名
 30
 31- `docs/firefox-manual-smoke`
 32
 33## 目标
 34
 35在真实 `Firefox.app` 环境里完成一轮手工 smoke,验证插件管理闭环、`tab_restore`、`ws_reconnect` 和状态回报恢复,并把结果回写到项目文档。
 36
 37## 背景
 38
 39当前代码和自动化测试已经覆盖了:
 40
 41- `GET /v1/browser`
 42- `POST /v1/browser/actions`
 43- `POST /v1/browser/request`
 44- `POST /v1/browser/request/cancel`
 45- 正式 SSE
 46- 结构化 `action_result`
 47- `shell_runtime`
 48
 49但当前仍缺一轮真实 Firefox 桌面环境下的手工验收。现有自动化 smoke 验证的是 conductor 侧协议和语义透传,不等于真实扩展运行时、真实 tab 生命周期和真实 WS 重连闭环。
 50
 51## 涉及仓库
 52
 53- `/Users/george/code/baa-conductor`
 54
 55## 范围
 56
 57- 真实 Firefox 扩展加载与握手确认
 58- `plugin_status`、`tab_open`、`tab_restore`、`ws_reconnect` 手工 smoke
 59- 浏览器端 tab 关闭 / 恢复 / 重连后的状态回报验证
 60- 验收结果记录和文档回写
 61
 62## 路径约束
 63
 64- 这张任务卡默认是“手工验证 + 文档回写”,不是代码修复任务
 65- 如果验证过程中发现真实 bug,先记录证据并新开 `bugs/BUG-XXX`,不要在同一任务里顺手修代码
 66- 只有当文档与真实行为不一致时,才回写文档;不要顺手改业务代码
 67
 68## 推荐实现边界
 69
 70建议优先做:
 71
 72- 先确认本地 `conductor` / Firefox 插件都处于可验证状态
 73- 再按固定场景顺序执行手工 smoke
 74- 最后把结果统一写回 `tasks/`、`plans/`、`PROGRESS/`;如有异常,再补 `bugs/`
 75
 76## 允许修改的目录
 77
 78- `/Users/george/code/baa-conductor/tasks/`
 79- `/Users/george/code/baa-conductor/plans/`
 80- `/Users/george/code/baa-conductor/PROGRESS/`
 81- `/Users/george/code/baa-conductor/bugs/`
 82- `/Users/george/code/baa-conductor/docs/api/`
 83- `/Users/george/code/baa-conductor/docs/firefox/`
 84
 85## 尽量不要修改
 86
 87- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/`
 88- `/Users/george/code/baa-conductor/plugins/baa-firefox/`
 89- `/Users/george/code/baa-conductor/tests/`
 90- `/Users/george/code/baa-conductor/packages/`
 91
 92## 必须完成
 93
 94### 1. 环境就绪确认
 95
 96- 确认真实 `Firefox.app` 可启动
 97- 确认插件已按临时扩展方式加载:`about:debugging#/runtime/this-firefox`
 98- 确认管理页显示:
 99  - `本地 WS = 已连接`
100  - `本地 HTTP = 已连接` 或处于明确重试
101- 确认本地接口可用:
102  - `GET /health`
103  - `GET /v1/browser`
104
105### 2. 执行手工 smoke 场景
106
107- 场景 A:基线握手与 `plugin_status`
108  - 触发 `plugin_status`
109  - 确认返回 `accepted=true`、`completed=true`
110  - 确认 `GET /v1/browser` 可看到当前 `client_id`、`last_action_result`、`shell_runtime`
111- 场景 B:`tab_open` + 登录态元数据
112  - 触发 Claude `tab_open`
113  - 如未登录,则在真实壳页完成登录
114  - 确认管理页和 `GET /v1/browser` 已出现账号、指纹、endpoint / shell runtime 信息
115- 场景 C:手动关闭 tab 后执行 `tab_restore`
116  - 手动关闭 Claude shell tab
117  - 触发 `plugin_status` 或等待状态刷新,确认 `actual` 缺失或 `drift` 不对齐
118  - 触发 `tab_restore`
119  - 确认新 tab 被恢复,且 `desired=true`、`actual.exists=true`、`drift.aligned=true`
120- 场景 D:执行 `ws_reconnect`
121  - 触发 `ws_reconnect`
122  - 确认 HTTP 返回里的 `completed=false`
123  - 在管理页观察 `本地 WS` 发生断开后重连
124  - 重连后确认 `GET /v1/browser` 仍能看到当前 client 和恢复后的状态回报
125- 场景 E:浏览器重开或扩展重载后的自动恢复
126  - 保持 Claude 在 `desired=true` 状态
127  - 关闭并重开 Firefox,或在 `about:debugging` 里重载扩展
128  - 确认插件管理页启动后会自动恢复缺失的 shell tab
129
130### 3. 记录结果并回写
131
132- 把每个场景写成 `通过 / 失败 / 阻塞`
133- 记录真实机器环境:
134  - macOS 版本
135  - Firefox 版本
136  - 验证时间
137  - 本地 API 地址
138- 把最终结论回写到:
139  - `/Users/george/code/baa-conductor/tasks/archive/T-S025.md`
140  - `/Users/george/code/baa-conductor/plans/STATUS_SUMMARY.md`
141  - `/Users/george/code/baa-conductor/PROGRESS/2026-03-27-current-code-progress.md`
142
143### 4. 异常处理
144
145- 如果某一步和当前文档结论不一致,记录最小复现步骤
146- 如属于新问题,新开 `bugs/BUG-XXX` 和对应 `FIX-BUG-XXX.md`
147- 不要在同一轮手工 smoke 任务里顺手改代码把问题“消掉”
148
149## 需要特别注意
150
151- `ws_reconnect` 的当前预期是“动作立即返回 `completed=false`,真实完成靠后续 `hello` / 状态同步体现”
152- `tab_restore` 要看的是“手工关 tab 后能否恢复 + 恢复后的状态是否回到 aligned”,不是只看 HTTP 200
153- 如果 Firefox 重开后自动恢复生效,要同时看:
154  - 浏览器里 tab 是否真的恢复
155  - `GET /v1/browser``shell_runtime` 是否同步恢复
156- 这轮不是 ChatGPT / Gemini relay 验收,除非顺手验证平台根页 adopt;否则默认以 Claude 为主验收面
157
158## 验收标准
159
160- 有一份真实 Firefox 手工 smoke 记录,覆盖 `plugin_status`、`tab_open`、`tab_restore`、`ws_reconnect`、浏览器重开 / 扩展重载自动恢复
161- 结果已明确写成 `通过 / 失败 / 阻塞`
162- 如发现异常,已补最小复现和 bug 卡
163- 相关状态文档已回写,不再只写“当前环境阻塞”
164
165## 推荐验证命令
166
167- `export LOCAL_API_BASE=http://100.71.210.78:4317`
168- `curl -s "${LOCAL_API_BASE}/health" | jq`
169- `curl -s "${LOCAL_API_BASE}/v1/browser" | jq '.data.current_client'`
170- `curl -s -X POST "${LOCAL_API_BASE}/v1/browser/actions" -H "content-type: application/json" -d '{"action":"plugin_status"}' | jq`
171- `curl -s -X POST "${LOCAL_API_BASE}/v1/browser/actions" -H "content-type: application/json" -d '{"action":"tab_open","platform":"claude"}' | jq`
172- `curl -s -X POST "${LOCAL_API_BASE}/v1/browser/actions" -H "content-type: application/json" -d '{"action":"tab_restore","platform":"claude"}' | jq`
173- `curl -s -X POST "${LOCAL_API_BASE}/v1/browser/actions" -H "content-type: application/json" -d '{"action":"ws_reconnect"}' | jq`
174
175## 真实 Firefox 手工 Smoke 记录(2026-03-27)
176
177- 机器:`mini`
178- macOS:`15.1 (24B2083)`
179- Firefox:`148.0.2`
180- 扩展加载方式:`about:debugging#/runtime/this-firefox` 临时扩展
181- LOCAL_API_BASE:`http://100.71.210.78:4317`
182- 验证时间:`2026-03-27 23:47:54 CST`
183
184### 场景 A:plugin_status
185
186- 结果:`通过`
187- 观察:`plugin_status` 返回 `accepted=true`、`completed=true`、`failed=false`;`/v1/browser` 能看到活跃 `client_id=firefox-73q0ro`、最新 `last_action_result``shell_runtime`188
189### 场景 B:tab_open + 元数据
190
191- 结果:`通过`
192- 观察:Claude `tab_open` 返回 `accepted=true`、`completed=true`;当前 Claude shell tab 维持在 `tab_id=18`,`/v1/browser?platform=claude` 可见账号、指纹、endpoint 元数据和 `aligned=true``shell_runtime`193
194### 场景 C:手动关 tab -> tab_restore
195
196- 结果:`通过`
197- 观察:手动关闭 Claude shell tab 后,`plugin_status` 正确反映 `actual_count=2`、`desired_count=3`、`drift_count=1`;执行 `tab_restore` 后,新 tab 被恢复,随后 `plugin_status` 回到 `actual_count=3`、`drift_count=0`。
198
199### 场景 D:ws_reconnect
200
201- 结果:`通过`
202- 观察:默认 `ws_reconnect` 返回 `completed=false`,随后通过新的 `hello` / 状态同步完成重连;额外用 `disconnect_ms=3000`、`repeat_count=3`、`repeat_interval_ms=500` 做了 3 轮重连稳定性验证,`connection_id` 依次从 `f8101883-1f4a-4bfa-9992-c5bd1497f5c5` 切换到 `45991b62-14a7-427f-96e9-9be21718fae1`、`afde2a15-0e3b-426b-adcb-af8065eadc30`、`c2b44e84-5d73-4944-88e9-36b6f1eeb914`,结束后 `plugin_status` 恢复到 `actual_count=3`、`desired_count=3`、`drift_count=0`。
203
204### 场景 E:浏览器重开 / 扩展重载自动恢复
205
206- 结果:`通过`
207- 观察:手动关闭 Claude shell tab 后重载扩展,`connection_id` 换新为 `4dbff2dc-dd81-4560-ba4d-e811162fd462`;扩展启动时先上报了一次 `missing_actual``request_credentials` 快照,随后自动恢复 Claude shell tab,最终 `plugin_status` 显示 Claude `tab_id=18`、`actual.exists=true`、`healthy=true`、`drift.aligned=true`。
208
209### 总结
210
211- 是否通过:`通过`
212- 新发现问题:`无`
213- 剩余风险:浏览器管理面真机验收已经完成;当前剩余主线风险转移到 `T-S035` / `T-S036`,即插件侧 delivery adapter 稳定性、binary-safe artifact delivery,以及既有 ChatGPT / Gemini 提取与 DOM heuristic 边界。