baa-conductor

git clone 

commit
39766c4
parent
8ef82d8
author
im_wower
date
2026-03-28 16:35:45 +0800 CST
docs: split current baa contract from roadmap
8 files changed,  +323, -872
A plans/BAA_INSTRUCTION_ROADMAP.md
+104, -0
  1@@ -0,0 +1,104 @@
  2+# BAA 指令系统路线图
  3+
  4+日期:`2026-03-28`
  5+
  6+> 这份文档只描述未来规划,不代表 `main` 当前正式合同。当前已生效的合同见 [`./BAA_INSTRUCTION_SYSTEM.md`](./BAA_INSTRUCTION_SYSTEM.md)。
  7+
  8+## 状态
  9+
 10+- `路线图 / 未来规划`
 11+- 当前基线:`main@8ef82d8`
 12+
 13+## 关联文档
 14+
 15+- [`./BAA_INSTRUCTION_SYSTEM.md`](./BAA_INSTRUCTION_SYSTEM.md)
 16+- [`./STATUS_SUMMARY.md`](./STATUS_SUMMARY.md)
 17+- [`./archive/BAA_BROWSER_PROXY_DELIVERY_REQUIREMENTS.md`](./archive/BAA_BROWSER_PROXY_DELIVERY_REQUIREMENTS.md)
 18+
 19+## 1. 近端方向
 20+
 21+当前主线已经完成了:
 22+
 23+- `browser.final_message` ingress
 24+- `@conductor` / `@system` / `@browser.claude`
 25+- proxy-first delivery
 26+
 27+下一步更合理的扩展顺序是:
 28+
 29+1. 先做稳定性收尾
 30+2. 再扩 target 面
 31+3. 最后做多节点 / 任务池 / 能力池
 32+
 33+## 2. 协议面扩展
 34+
 35+未来计划支持但当前还未放开的 target:
 36+
 37+- `browser.chatgpt`
 38+- `browser.gemini`
 39+- `codex`
 40+- `node.mini` / `node.mbp`
 41+- `pool.*`
 42+- `role.*`
 43+
 44+对应目标:
 45+
 46+- 把 `browser.chatgpt` / `browser.gemini` 做成正式 BAA target,而不只是 relay 来源
 47+- 把 `codex` / `node.*` 从当前讨论状态升级成正式协议层
 48+- 后续再引入 capability pool 和 role pool
 49+
 50+## 3. delivery 继续演进
 51+
 52+当前 delivery 已经从 shell-page DOM 回写收口到 proxy-first。后续路线图是:
 53+
 54+- 继续压缩 DOM fallback 的触发面
 55+- 让 proxy send 更少依赖最近观测到的真实发送模板
 56+- 把成功语义从“请求已派发”推进到“下游 AI 已给出可观察回复”
 57+- 完善多页、多 org、多会话的精确 route
 58+
 59+## 4. 指令系统继续扩面
 60+
 61+未来可扩的 tool 面包括:
 62+
 63+- 更完整的 `browser.*`
 64+- `codex/sessions`
 65+- `codex/turn`
 66+- `tasks`
 67+- 更细的系统管理能力
 68+
 69+但扩面原则不变:
 70+
 71+- conductor 仍是唯一解释中心
 72+- 插件仍保持 thin-plugin
 73+- 解析、路由、权限、审计都不回流到插件
 74+
 75+## 5. 编排层路线
 76+
 77+当前主线仍是单节点、单轮主线。后续路线图包括:
 78+
 79+- 多客户端并发 delivery
 80+- 多节点执行路由
 81+- `pool.*` 能力池
 82+- `role.*` 角色池
 83+- 长任务 / 后台任务池
 84+
 85+这些都属于后续阶段,不应混入当前正式合同。
 86+
 87+## 6. 明确不回头的方向
 88+
 89+除非需求重新变化,当前路线图不打算回到:
 90+
 91+- artifact upload / download 主链
 92+- binary delivery 主链
 93+- 插件侧复杂编排
 94+- 插件侧 BAA parser
 95+
 96+当前更清晰的方向仍然是:
 97+
 98+- conductor 负责上下文、路由和审计
 99+- 插件负责页面内真实请求执行
100+
101+## 7. 阅读顺序
102+
103+1. [`./BAA_INSTRUCTION_SYSTEM.md`](./BAA_INSTRUCTION_SYSTEM.md)
104+2. [`./STATUS_SUMMARY.md`](./STATUS_SUMMARY.md)
105+3. 本文档
M plans/BAA_INSTRUCTION_SYSTEM.md
+123, -862
   1@@ -1,934 +1,195 @@
   2-# BAA 指令系统
   3+# BAA 指令系统(当前正式合同)
   4 
   5-日期:2026-03-28
   6+日期:`2026-03-28`
   7 
   8-> 让任何 AI 通过代码块驱动外部能力——shell、文件、浏览器代发、跨 AI 能力借用——不需要原生 function calling。
   9+> 这份文档只描述 `main` 当前已经成立的正式合同。未来目标、扩展 target 和远期编排,统一移到 [`./BAA_INSTRUCTION_ROADMAP.md`](./BAA_INSTRUCTION_ROADMAP.md)。
  10 
  11-## 0. 当前实现状态
  12+## 状态
  13 
  14-这份文档同时包含“当前已实现能力”和“后续规划目标”。当前代码主线请先按下面这组事实理解:
  15+- `当前正式合同`
  16+- 当前主分支:`main@8ef82d8`
  17+- canonical local API:`http://100.71.210.78:4317`
  18+- canonical public host:`https://conductor.makefile.so`
  19 
  20-- 当前正式支持的 target 只有:
  21-  - `conductor`
  22-  - `system`
  23-  - `browser.claude`
  24-- `browser.chatgpt` / `browser.gemini` 目前仍是规划目标,不是当前放开的 Phase 1 target
  25-- upload / download / binary delivery 已经废弃,不再是当前插件职责
  26-- 当前 delivery 主链已经是 proxy-first,DOM `inject / send` 仅作 fallback
  27-- 当前主线已经由 conductor 持有 conversation / routing 真相,插件只执行 page-context browser request
  28+## 关联文档
  29 
  30----
  31+- [`./STATUS_SUMMARY.md`](./STATUS_SUMMARY.md)
  32+- [`./BAA_INSTRUCTION_ROADMAP.md`](./BAA_INSTRUCTION_ROADMAP.md)
  33+- [`./archive/BAA_BROWSER_PROXY_DELIVERY_REQUIREMENTS.md`](./archive/BAA_BROWSER_PROXY_DELIVERY_REQUIREMENTS.md)
  34+- [`../docs/AI_BAA_QUICKSTART.md`](../docs/AI_BAA_QUICKSTART.md)
  35 
  36-## 1. 核心规则
  37+## 1. 当前范围
  38 
  39-### 1.1 一个代码块 = 一条指令
  40+当前 `main` 里,BAA 指令系统已经收口到这条主链:
  41 
  42-一个 ` ```baa ``` ` 代码块只包含一条指令,多条指令用多个代码块表达。
  43+- AI 页面输出 ` ```baa ` 代码块
  44+- Firefox 插件把最终回复转成 `browser.final_message`
  45+- conductor 负责提取、解析、去重、权限校验、执行和结果回写
  46+- 回写主链是 proxy-first:
  47+  - 优先 `browser.proxy_delivery`
  48+  - 失败时才退回 DOM `inject / send`
  49 
  50-好处:
  51-- 多个代码块 → 多条指令 → **并行执行**
  52-- 语义清晰:一块一事
  53-- 和 conductor 的异步模式一致(并行提交 → sleep → 单次 poll)
  54-- 去重粒度稳定、风险边界清晰
  55+职责边界固定如下:
  56 
  57-### 1.2 双平面模型
  58+- conductor:唯一解释中心、唯一路由真相源、唯一审计点
  59+- 插件:观察最终回复、在 page context 执行真实请求、必要时做最小 fallback
  60 
  61-**控制面**:` ```baa ` 代码块,可执行、可路由、可审计。
  62+## 2. 语法合同
  63 
  64-**内容面**:普通 Markdown、自然语言、`[REQUEST_CONTEXT]`、`[STRESS_TEST]`、`[COUNTER_FACTUAL]`、`LOCKED` 等协作协议。
  65+### 2.1 一个代码块 = 一条指令
  66 
  67-两者配合但不混在一起。BAA 指令系统只负责控制面。
  68+一个 ` ```baa ``` ` 代码块只表示一条指令。多条独立指令用多个代码块表示,默认并行。
  69 
  70-### 1.3 conductor 是唯一解释中心
  71+### 2.2 基本格式
  72 
  73-插件不解析 baa 代码块。所有解析、路由、去重、权限、执行、结果总结、交付计划都在 conductor 内完成。
  74-
  75-插件只做三件事:
  76-- **观察**:拦截 AI 最终回复,转发给 conductor
  77-- **执行**:在页面上下文里带真实登录态执行 browser request
  78-- **回退**:必要时按 conductor 指示做最小 text-only 注入/发送 fallback
  79-
  80-这样无论接多少个平台,解析、路由、权限和上下文真相都仍留在 conductor,而不是散落到插件里。
  81-
  82-### 1.4 语法极简,复杂度后移
  83-
  84-AI 最容易忘的是复杂格式,不容易忘的是代码块。语法层保持极简,复杂度后移到 conductor 内部。
  85-
  86----
  87-
  88-## 2. 指令格式
  89-
  90-### 2.1 三段式:谁 :: 干什么 :: 怎么干
  91-
  92-```
  93+```text
  94 @target::tool::params
  95 ```
  96 
  97-### 2.2 语法文法
  98-
  99-```ebnf
 100-instruction_block = "```baa" , newline , instruction_text , newline? , "```" ;
 101-instruction_text = first_line , ( newline , body )? ;
 102-first_line = "@" , target , "::" , tool , ( "::" , inline_params )? ;
 103-target = token , { "." , token } ;
 104-tool = token , { "/" , token } ;
 105-body = { any_char } ;
 106-token = 1*( ALPHA / DIGIT / "_" / "-" ) ;
 107-```
 108-
 109-### 2.3 四种参数形式
 110-
 111-**A. 单行字符串参数**
 112-
 113-    ```baa
 114-    @conductor::exec::ls -la ~/code
 115-    ```
 116-
 117-**B. 单行 JSON 参数**
 118-
 119-    ```baa
 120-    @conductor::files/read::{"path": "~/Desktop/HANDOFF.md"}
 121-    ```
 122-
 123-**C. 多行参数**
 124-
 125-第一行是 `@target::tool`(没有 `::params`),后续所有行拼接为这一条指令的参数:
 126-
 127-    ```baa
 128-    @conductor::exec
 129-    cd ~/code/baa-conductor
 130-    git status
 131-    git log --oneline -3
 132-    ```
 133-
 134-**D. 无参数**
 135-
 136-    ```baa
 137-    @conductor::describe
 138-    ```
 139-
 140-### 2.4 并行执行示例
 141-
 142-AI 回复中出现 3 个 baa 代码块 = 3 条独立指令 = 并行提交:
 143-
 144-    我来同时检查几个东西:
 145-
 146-    ```baa
 147-    @conductor::exec::ls /tmp
 148-    ```
 149-
 150-    ```baa
 151-    @conductor::files/read::{"path":"~/Desktop/HANDOFF.md"}
 152-    ```
 153-
 154-    ```baa
 155-    @conductor::describe
 156-    ```
 157-
 158-代码块之间的普通文本被忽略,只提取 baa 块。
 159-
 160----
 161-
 162-## 3. 目标地址(target)
 163-
 164-### 3.1 精确 target
 165-
 166-| target | 含义 | 路由到 |
 167-|---|---|---|
 168-| `conductor` / `system` | conductor 本机 | conductor local API |
 169-| `browser.claude` | Claude 平台 | `/v1/browser/request` platform=claude |
 170-| `browser.chatgpt` | ChatGPT 平台 | `/v1/browser/request` platform=chatgpt |
 171-| `browser.gemini` | Gemini 平台 | `/v1/browser/request` platform=gemini |
 172-| `codex` | codexd 代理 | `/v1/codex/*` |
 173-| `node.mini` / `node.mbp` | 指定机器节点 | SSH / tailscale 执行 |
 174-
 175-注意:
 176-
 177-- 上表是协议目标全集,不等于当前已开放实现
 178-- 当前真正放开的 Phase 1 target 仍只有 `conductor` / `system` / `browser.claude`
 179-
 180-### 3.2 逻辑 target(Phase 4+)
 181-
 182-| target | 含义 | 路由方式 |
 183-|---|---|---|
 184-| `pool.image` | 能生图的节点 | conductor 按能力声明选择 |
 185-| `pool.video` | 能生视频的节点 | 同上 |
 186-| `pool.http` | 能发 HTTP 的节点 | 同上 |
 187-| `role.reviewer` | 审阅角色 | conductor 按角色分配 |
 188-| `role.coder` | 编码角色 | 同上 |
 189-
 190-精确寻址与能力路由共存。首版只做精确 target。
 191-
 192----
 193-
 194-## 4. 工具映射(tool → conductor API)
 195-
 196-| tool | conductor API | 说明 |
 197-|---|---|---|
 198-| `exec` | `POST /v1/exec` | 执行 shell 命令 |
 199-| `files/read` | `POST /v1/files/read` | 读文件 |
 200-| `files/write` | `POST /v1/files/write` | 写文件 |
 201-| `describe` | `GET /describe` | 系统自描述 |
 202-| `describe/business` | `GET /describe/business` | 业务面 |
 203-| `describe/control` | `GET /describe/control` | 控制面 |
 204-| `status` | `GET /v1/status` | 状态视图 |
 205-| `browser/status` | `GET /v1/browser` | 浏览器状态 |
 206-| `browser/request` | `POST /v1/browser/request` | 通用代发 |
 207-| `browser/actions` | `POST /v1/browser/actions` | 插件管理 |
 208-| `send` | 平台对话发送 | browser target 专用 |
 209-| `current` | 读当前对话 | browser target 专用 |
 210-| `codex/sessions` | `POST /v1/codex/sessions` | 创建 codex session |
 211-| `codex/turn` | `POST /v1/codex/turn` | 发 codex turn |
 212-| `tasks` | `GET /v1/tasks` | 查看任务 |
 213-
 214-先实现 `describe / status / exec / files / send / current` 即可跑通闭环。
 215-
 216----
 217-
 218-## 5. 能力互补:每个 AI 都是别人的手
 219-
 220-### 5.1 各 AI 的能力边界
 221-
 222-| AI | 能做 | 不能做 |
 223-|---|---|---|
 224-| Claude | 网络请求(GET/POST)、代码执行、文件操作 | 生图、生视频、生音频 |
 225-| ChatGPT | 生图(DALL-E/GPT-Image)、代码执行、GET 请求 | POST 请求、直接操作远程服务器 |
 226-| Gemini | 生图(Imagen)、生视频 | 网络请求、POST、访问外部 API |
 227+### 2.3 当前支持的参数形式
 228 
 229-注意:这是当前经验,不是永恒事实。系统实现时应改成节点自描述 + conductor 路由,而不是硬编码。
 230+- 单行字符串参数
 231+- 单行 JSON 参数
 232+- 多行参数
 233+- 无参数
 234 
 235-### 5.2 跨 AI 能力借用示例
 236+示例:
 237 
 238-**Gemini 借 shell 能力**:
 239-
 240-    ```baa
 241-    @conductor::exec::git status
 242-    ```
 243-
 244-**ChatGPT 借 POST 能力**:
 245-
 246-    ```baa
 247-    @conductor::exec::curl -X POST https://api.example.com/webhook -d '{"event":"deploy"}'
 248-    ```
 249-
 250-**Claude 借生图能力**:
 251-
 252-    ```baa
 253-    @browser.chatgpt::send::请生成一张赛博朋克风格的城市夜景图,4K 分辨率
 254-    ```
 255-
 256-**Claude 借生视频能力**:
 257-
 258-    ```baa
 259-    @browser.gemini::send::请生成一段 5 秒的视频:一只猫在键盘上打字
 260-    ```
 261-
 262-### 5.3 架构角色
 263-
 264-```
 265-conductor     = 唯一中控,提取指令、路由、执行、总结、保存上下文并决定回写目标
 266-Firefox 插件  = 薄网关,观察回复、执行 page-context 请求、必要时做最小 fallback 回写
 267-各 AI         = 能力节点,各有所长,通过 baa 代码块互相借用
 268-```
 269-
 270----
 271-
 272-## 6. 端到端链路:从 AI 回复到结果回传
 273-
 274-### 6.1 现有基础设施
 275-
 276-插件已有完整的 SSE 拦截→WS 转发链路:
 277-
 278-```
 279-页面 fetch()
 280-→ page-interceptor.js hook(streamSse / streamProxyResponse)
 281-→ 逐 chunk 通过 content-script 发给 controller.js
 282-→ controller.js handlePageSse()
 283-→ wsSend() 通过 WS 发给 conductor
 284+```baa
 285+@conductor::exec::pwd
 286 ```
 287 
 288-当前 `handlePageSse()` 对有机回复(用户正常聊天)只更新本地状态就 return 了。只需在 `done === true` 时加一个 `wsSend` 把完整回复文本转发给 conductor,整条链路就打通。
 289-
 290-### 6.2 完整闭环
 291-
 292-```
 293-用户 / AI 在网页对话
 294-→ 页面 fetch() 被 page-interceptor hook
 295-→ SSE chunks 逐个转发给 controller.js
 296-→ 回复完成(done=true)时,controller 拼接完整文本
 297-→ wsSend({ type: "assistant_message_complete", text, platform, conversationId })
 298-→ conductor 收到完整回复文本
 299-→ conductor extractBaaBlocks()
 300-→ conductor parseBaaBlock() × N
 301-→ conductor 去重 + 权限校验
 302-→ conductor 并行执行(exec / files / browser/request / codex)
 303-→ conductor 汇总结果
 304-→ conductor 生成 delivery route(当前默认 text-only;旧 artifact 方案已废弃)
 305-→ WS / browser request 指示插件执行回写
 306-→ 插件执行 page-context 请求,或在 fallback 模式下注入文本 / 点击发送
 307-→ AI 看到结果,继续工作
 308+```baa
 309+@conductor::files/read::{"path":"README.md"}
 310 ```
 311 
 312-### 6.3 插件侧改动量
 313-
 314-只需在 controller.js 的 `handlePageSse` 中加一段:
 315-
 316-```javascript
 317-// 有机回复完成时,转发全文给 conductor
 318-if (data.done && !pending) {
 319-  const fullText = getAccumulatedSseText(context.platform, context.conversationId);
 320-  if (fullText) {
 321-    wsSend({
 322-      type: "assistant_message_complete",
 323-      platform: context.platform,
 324-      conversationId: getConversationId(context),
 325-      messageId: getLastAssistantMessageId(context),
 326-      text: fullText
 327-    });
 328-  }
 329-}
 330+```baa
 331+@conductor::exec
 332+cd .
 333+git status
 334 ```
 335 
 336-其余所有逻辑(解析、执行、总结、交付计划)都在 conductor 侧。
 337+### 2.4 当前解析规则
 338 
 339----
 340+- 只解析最终权威消息,不在 streaming 半截文本上执行
 341+- 只解析 ` ```baa ` 代码块,不执行普通代码块
 342+- 每个 block 独立去重
 343 
 344-## 7. 解析器(conductor 侧)
 345+## 3. 当前正式 target
 346 
 347-### 7.1 提取 baa 代码块
 348-
 349-```javascript
 350-function extractBaaBlocks(text) {
 351-  const blocks = [];
 352-  const re = /```baa\s*\n([\s\S]*?)```/g;
 353-  let m;
 354-  while ((m = re.exec(text)) !== null) {
 355-    const body = m[1].trim();
 356-    if (body) blocks.push(body);
 357-  }
 358-  return blocks;
 359-}
 360-```
 361-
 362-### 7.2 解析单条指令
 363-
 364-```javascript
 365-function parseBaaBlock(blockText) {
 366-  const lines = blockText.split('\n');
 367-  const firstLine = lines[0].trim();
 368-  const m = firstLine.match(/^@([^:\s]+)::([^:\s]+)(?:::([\s\S]*))?$/);
 369-  if (!m) return null;
 370-
 371-  const target = m[1];
 372-  const tool = m[2];
 373-  const inlineParams = m[3] ? m[3].trim() : null;
 374-
 375-  if (inlineParams !== null) {
 376-    return { target, tool, params: parseParamValue(inlineParams) };
 377-  }
 378-
 379-  const rest = lines.slice(1).join('\n').trim();
 380-  return rest
 381-    ? { target, tool, params: { command: rest } }
 382-    : { target, tool, params: {} };
 383-}
 384-
 385-function parseParamValue(raw) {
 386-  if (!raw) return {};
 387-  if (raw.startsWith('{')) {
 388-    try { return JSON.parse(raw); } catch { /* fall through */ }
 389-  }
 390-  return { command: raw };
 391-}
 392-```
 393-
 394-### 7.3 只解析最终权威消息
 395-
 396-不在 streaming 半截文本上执行。必须等 `assistant_message_complete` 到达 conductor 后再提取。
 397-
 398----
 399-
 400-## 8. 结果交付(历史设计,已废弃)
 401-
 402-本章描述的是早期“文件上传优先、文本兜底”的 artifact 交付方案。它已经不是当前主线实现,保留这里只是为了回溯设计演进。
 403-
 404-当前实际主线请按下面这组事实理解:
 405-
 406-- artifact upload / download 已废弃
 407-- 当前 delivery 已经是 proxy-first,DOM `inject / send` 只保留为 fallback
 408-- 代理式 delivery 收口记录见 [`./archive/BAA_BROWSER_PROXY_DELIVERY_REQUIREMENTS.md`](./archive/BAA_BROWSER_PROXY_DELIVERY_REQUIREMENTS.md)
 409-- 不要再把本章里的 upload receipt / manifest / 文件上传流程当成当前合同
 410-
 411-### 8.1 分层策略
 412-
 413-| 结果大小 | 交付方式 | 场景 |
 414+| target | 状态 | 说明 |
 415 |---|---|---|
 416-| 小(< 500 字) | 文本注入 | pwd、describe、短输出 |
 417-| 中/大(≥ 500 字) | 文件上传 + 索引文本 | 读文件、日志、git diff |
 418-| 文件上传失败 | 降级为截断文本(2000 字 + 摘要) | 兜底 |
 419+| `conductor` | 正式支持 | 本机 conductor API |
 420+| `system` | 正式支持 | `conductor` 的别名视角 |
 421+| `browser.claude` | 正式支持 | Phase 1 唯一已放开的 browser target |
 422+| `browser.chatgpt` | 未放开 | 仍在路线图,不是当前正式 target |
 423+| `browser.gemini` | 未放开 | 仍在路线图,不是当前正式 target |
 424+| `codex` / `node.*` / `pool.*` / `role.*` | 未放开 | 仍在路线图 |
 425 
 426-### 8.2 为什么文件上传优于贴文本
 427+## 4. 当前正式 tool 面
 428 
 429-| 维度 | 文本注入 | 文件上传 |
 430-|---|---|---|
 431-| Context window 占用 | 直接吃上下文 | 走附件通道,占用更小 |
 432-| 大结果处理 | 500 行日志撑爆对话 | 文件天然承载大内容 |
 433-| 结构化 | 需要解析前缀 | 文件名即元数据 |
 434-| 多结果并行 | 一大坨拼接文本 | 多个文件,清晰分离 |
 435+### 4.1 `@conductor` / `@system`
 436 
 437-### 8.3 Artifact 生命周期(conductor 侧)
 438+当前正式支持:
 439 
 440-```
 441-raw execution results
 442-→ summarize(每条指令生成一行摘要)
 443-→ materialize artifacts(大结果写成文件)
 444-→ build manifest(汇总所有 artifact 的索引)
 445-→ build delivery plan(决定哪些上传、哪些文本注入)
 446-→ WS 指示插件执行
 447-→ 插件上传文件 → 返回 upload receipt
 448-→ 所有上传确认后,conductor 生成索引文本
 449-→ WS 指示插件注入索引文本并发送
 450-```
 451+- `describe`
 452+- `describe/business`
 453+- `describe/control`
 454+- `status`
 455+- `exec`
 456+- `files/read`
 457+- `files/write`
 458+- `browser/status`
 459+- `browser/actions`
 460 
 461-关键原则:**上传成功后才发送索引文本**。没有确认就注入,AI 会看到"结果见附件"但附件还没出现。
 462+### 4.2 `@browser.claude`
 463 
 464-### 8.4 文件上传实现(插件侧)
 465+当前 Phase 1 正式支持:
 466 
 467-各平台的 AI 对话输入框都有文件上传入口。插件通过模拟文件拖拽上传:
 468+- `send`
 469+- `current`
 470 
 471-```javascript
 472-async function uploadResultFile(platform, filename, content) {
 473-  const blob = new Blob([content], { type: 'text/plain' });
 474-  const file = new File([blob], filename, { type: 'text/plain' });
 475+说明:
 476 
 477-  const dropZone = findDropZone(platform);
 478-  if (!dropZone) return false;
 479+- `browser.request` 是浏览器桥接的底层正式能力
 480+- 但对 AI 暴露成 BAA 指令时,当前只正式放开 `browser.claude`
 481 
 482-  const dt = new DataTransfer();
 483-  dt.items.add(file);
 484-  dropZone.dispatchEvent(new DragEvent('drop', { dataTransfer: dt, bubbles: true }));
 485-  return true;
 486-}
 487-```
 488+## 5. 当前 ingress / delivery 合同
 489 
 490-上传后需确认附件 chip 出现才算成功。
 491+### 5.1 ingress
 492 
 493-### 8.5 文件命名规范
 494+当前三个页面平台都可作为 `browser.final_message` 的来源:
 495 
 496-```
 497-baa-result_{tool}_{target}_{status}.md
 498-```
 499+- `ChatGPT`
 500+- `Claude`
 501+- `Gemini`
 502 
 503-示例:`baa-result_exec_conductor_ok.md`、`baa-result_files-read_conductor_ok.md`
 504+这表示它们都能把最终回复送进 conductor 的 ingest 主链;不表示它们都已经成为正式 BAA browser target。
 505 
 506-### 8.6 推荐文件类型
 507+### 5.2 delivery
 508 
 509-不强制所有结果都是 `.md`:
 510+当前正式 delivery 合同如下:
 511 
 512-| 内容 | 文件类型 |
 513-|---|---|
 514-| 日志 | `.log` |
 515-| JSON | `.json` |
 516-| diff | `.patch` |
 517-| CSV | `.csv` |
 518-| 摘要 | `.md` |
 519-| 图片 | `.png` |
 520-| 视频 | `.mp4` |
 521+- conductor 记录最近观察到的 conversation / page route
 522+- 回写优先走 `browser.proxy_delivery`
 523+- 插件只在目标页面上下文里执行真实请求
 524+- DOM `browser.inject_message` / `browser.send_message` 只保留为 fallback
 525 
 526-### 8.7 索引文本格式
 527+### 5.3 成功语义
 528 
 529-上传完成后注入的文本:
 530+当前 `proxy_delivery` 的成功语义是:
 531 
 532-```
 533-[BAA 结果索引]
 534-- @conductor::exec::ls /tmp → 成功(结果见 baa-result_exec_conductor_ok.md)
 535-- @conductor::files/read → 成功(结果见 baa-result_files-read_conductor_ok.md)
 536-- @conductor::describe → 成功(内联)
 537+- 请求已经成功派发到目标页面上下文
 538 
 539-describe 结果:
 540-{"deployment_mode": "single-node mini", ...}
 541-```
 542+当前不保证:
 543 
 544-小结果内联在索引文本里,大结果只给摘要+文件名引用。
 545+- 下游 AI 已经完整回复
 546+- 平台已经把这一轮响应持久写回业务线程
 547 
 548-### 8.8 文本兜底格式
 549+## 6. 当前明确不包含
 550 
 551-所有上传都失败时,降级为纯文本注入:
 552+下面这些不属于当前正式合同:
 553 
 554-```
 555-[BAA 执行结果]
 556+- `browser.chatgpt` / `browser.gemini` 正式 BAA target
 557+- upload / download / binary delivery
 558+- artifact / manifest / upload receipt 方案
 559+- 多客户端、多节点 orchestrator
 560+- `pool.*` / `role.*` 能力池和角色池
 561+- `codex` / `node.*` 的完整路由协议
 562+- 任务池与后台长流程
 563 
 564---- @conductor::exec::ls /tmp ---
 565-成功:
 566-file1.txt
 567-file2.txt
 568-(输出已截断,完整结果 2.3KB)
 569-```
 570+## 7. 当前已知边界
 571 
 572-### 8.9 下载流
 573+- `Gemini` 还不是 `/v1/browser/request` 的正式支持面
 574+- ChatGPT proxy send 仍依赖最近捕获的真实发送模板;冷启动时可能退回 DOM fallback
 575+- Claude 的 `organizationId` 仍依赖最近观测到的 org 上下文
 576+- relay / dedupe / delivery 仍主要服务于单节点主线
 577 
 578-当目标 AI 返回图片/视频/文件时:
 579+## 8. 当前最小示例
 580 
 581-```
 582-conductor 生成 download plan
 583-→ WS 指示插件下载
 584-→ 插件下载文件 → 回传本地路径
 585-→ conductor 决定:存档 / 转发给其他 AI / 摘要
 586-```
 587-
 588----
 589-
 590-## 9. 执行闭环与状态机
 591-
 592-### 9.1 状态流转
 593-
 594-```
 595-Idle
 596-→ WaitingFinalMessage(assistant streaming)
 597-→ Extracting(assistant_message_complete 到达 conductor)
 598-  → Idle(no baa blocks)
 599-  → Normalizing(found baa blocks)
 600-→ DedupeCheck
 601-  → Idle(all duplicate)
 602-  → PolicyCheck(new instructions)
 603-→ Dispatching(allowed)
 604-→ WaitingResults
 605-→ MaterializingArtifacts
 606-→ BuildingManifest
 607-→ BuildingDeliveryPlan
 608-→ PluginUploading
 609-→ WaitingUploadAck
 610-  → InjectingIndex(all uploads confirmed)
 611-  → DeliveryFailed(upload timeout / failed → 降级文本兜底)
 612-→ CoolingDown
 613-  → WaitingFinalMessage(auto-next-turn)
 614-  → Idle(stop condition reached)
 615-
 616-Pause / Resume / Drain 可在任何活跃状态触发。
 617-DeliveryFailed → Idle
 618-```
 619-
 620-### 9.2 并行与顺序
 621-
 622-多个 baa block = 并行执行。有严格顺序依赖时用单个多行 exec 或分成多轮。
 623-
 624-### 9.3 终止条件
 625-
 626-满足任一条件停止自动循环:
 627-- hop limit 达上限(默认 10)
 628-- 连续失败达阈值(默认 3)
 629-- 用户手动输入(人工抢占最高优先级)
 630-- 系统 pause / drain
 631-- 下一轮回复没有 baa 指令
 632-- 路由器找不到合法目标
 633-- artifact 上传持续失败
 634-
 635-### 9.4 冷却与节流
 636-
 637-- 每轮注入后冷却 2 秒
 638-- 同轮最大并发数:8
 639-- 结果注入总字符数限制:32KB(超出走文件上传)
 640-- 单轮总上传大小限制:可配置
 641-
 642-### 9.5 核心规则
 643-
 644-1. **只解析最终权威消息**——不在 streaming 中途解析
 645-2. **只解析 ` ```baa `**——不执行普通代码块
 646-3. **每个 block 独立去重**——同一条消息的第 0 块和第 1 块分开跟踪
 647-4. **结果先产物化,再决定怎么交付**——不直接把 raw output 塞回对话
 648-5. **上传成功后才发送索引文本**——避免"结果见附件"但附件没到
 649-6. **用户输入优先级最高**——用户开始打字时自动注入立即让路
 650-
 651----
 652-
 653-## 10. 权限与安全
 654-
 655-### 10.1 风险分层
 656-
 657-| 层级 | 示例 | 默认策略 |
 658-|---|---|---|
 659-| Tier 0 只读 | describe, status, files/read, tasks | 自动执行 |
 660-| Tier 1 低风险写 | 工作区 files/write, browser send | 自动执行 + 审计 |
 661-| Tier 2 执行/网络 | exec, curl, git 写操作 | 白名单或 shared token |
 662-| Tier 3 危险操作 | rm -rf, 系统 reload, credential 操作 | 必须人工批准 |
 663-
 664-### 10.2 三道边界
 665-
 666-- **语法边界**:只执行 ` ```baa `,不执行普通代码块
 667-- **权限边界**:解析成功 ≠ 允许执行
 668-- **环境边界**:token / sandbox / workspace path allowlist
 669-
 670-### 10.3 审计日志
 671-
 672-每条指令至少记录:instruction_id、source_node、target、tool、risk_tier、policy_decision、started_at、finished_at、result_summary、delivery_plan_id、upload_receipt_hash。
 673-
 674-### 10.4 人工接管点
 675-
 676-- 执行前(高风险)
 677-- 结果注入前(可编辑)
 678-- 路由失败后(人工改派)
 679-- 连续失败熔断后
 680-
 681----
 682-
 683-## 11. conductor 内部标准化
 684-
 685-### 11.1 Envelope
 686-
 687-conductor 收到 `assistant_message_complete`,提取 baa 块后转为标准化对象:
 688-
 689-```typescript
 690-interface NormalizedInstruction {
 691-  instructionId: string;
 692-  traceId: string;
 693-  conversationId: string | null;
 694-  assistantMessageId: string | null;
 695-  blockIndex: number;
 696-  sourceNode: string;
 697-  target: string;
 698-  tool: string;
 699-  params: Record<string, unknown>;
 700-  riskTier: "tier0" | "tier1" | "tier2" | "tier3";
 701-  dedupeKey: string;
 702-  roundId: string | null;
 703-  hop: number;
 704-  createdAt: number;
 705-}
 706-```
 707-
 708-### 11.2 去重键
 709-
 710-```
 711-dedupe_key = sha256(platform | conversation_id | assistant_message_id | block_index | normalized_block_text)
 712-```
 713-
 714-### 11.3 路由决策
 715-
 716-```typescript
 717-interface RouteDecision {
 718-  resolvedTarget: string;
 719-  resolvedNodeId?: string;
 720-  routeReason: string[];
 721-  fallbackCandidates: string[];
 722-}
 723-```
 724-
 725-首版只做精确路由(conductor / browser.* / codex),Phase 4 加能力池打分路由。
 726-
 727-### 11.4 Delivery Plan
 728-
 729-```typescript
 730-interface DeliveryPlan {
 731-  planId: string;
 732-  traceId: string;
 733-  conversationId: string | null;
 734-  target: string;
 735-  uploads: DeliveryUploadItem[];
 736-  messageText: string;
 737-  autoSend: boolean;
 738-}
 739-
 740-interface DeliveryUploadItem {
 741-  artifactId: string;
 742-  filename: string;
 743-  mimeType: string;
 744-  localPath: string;
 745-}
 746-
 747-interface UploadReceipt {
 748-  artifactId: string;
 749-  ok: boolean;
 750-  remoteHandle?: string;
 751-  errorCode?: string;
 752-}
 753-```
 754-
 755----
 756+### 本机执行
 757 
 758-## 12. 与当前 baa-conductor 的对接
 759-
 760-### 12.1 当前已有的基础
 761-
 762-**插件侧(已到位)**:
 763-- page-interceptor.js:fetch hook + SSE 拦截 + 逐 chunk 转发
 764-- controller.js:handlePageSse + wsSend → WS 转发给 conductor
 765-- 文本注入能力(injectText)
 766-- 文件拖拽上传能力(DataTransfer 模拟)
 767-
 768-**conductor 侧(已到位)**:
 769-- local API:exec / files / browser / codex / tasks / describe / status / pause/resume/drain
 770-- firefox-ws.ts:WS 消息接收和分发
 771-- firefox-bridge.ts:stream session(seq tracking、buffer overflow、idle timeout)
 772-- browser-request-policy.ts:限流/抖动/退避/熔断
 773-- packages/db:SQLite 存储
 774-- packages/auth:token 验证
 775-
 776-### 12.2 需要新增的
 777-
 778-**插件侧(改动极小)**:
 779-- handlePageSse 中 `done === true` 且非代理请求时,`wsSend` 转发完整回复文本
 780-- 接收 conductor 的 delivery plan 并执行(上传文件 + 注入文本)
 781-
 782-**conductor 侧(新增模块)**:
 783-
 784-```
 785-apps/conductor-daemon/src/instructions/
 786-  extract.ts          ← extractBaaBlocks
 787-  parse.ts            ← parseBaaBlock
 788-  normalize.ts        ← 标准化 envelope + 去重键
 789-  dedupe.ts           ← 去重缓存
 790-  policy.ts           ← 风险分层 + 权限校验
 791-  router.ts           ← 精确路由 + 能力池(Phase 4)
 792-  executor.ts         ← 并行执行 + 结果汇总
 793-  artifact.ts         ← 产物化 + manifest
 794-  delivery.ts         ← delivery plan 生成
 795-  loop.ts             ← 状态机 + 自动循环控制
 796+```baa
 797+@conductor::exec::pwd
 798 ```
 799 
 800-firefox-ws.ts 新增消息类型:
 801-- 接收:`assistant_message_complete`(插件转发的 AI 完整回复)
 802-- 发送:`delivery_plan`(指示插件上传/注入)
 803-- 接收:`upload_receipt`(插件上传结果确认)
 804-
 805----
 806-
 807-## 13. AI 侧提示词
 808-
 809-### 通用提示词(适用于 Claude / ChatGPT / Gemini)
 810+### 读文件
 811 
 812+```baa
 813+@conductor::files/read::{"path":"README.md"}
 814 ```
 815-你可以通过 baa 代码块请求外部能力。
 816 
 817-规则:
 818-1. 只在确实需要外部操作时输出 ```baa 代码块。
 819-2. 一个代码块只包含一条指令。
 820-3. 多条独立指令用多个代码块,默认并行执行。
 821-4. 优先读操作,再写操作,再高风险执行。
 822-5. 展示示例代码时不要用 baa 代码块。
 823-6. 借别的平台能力用精确 target(如 @browser.chatgpt::send)。
 824+### Claude browser target
 825 
 826-基本格式:
 827-
 828-    ```baa
 829-    @conductor::exec::pwd
 830-    ```
 831-
 832-    ```baa
 833-    @conductor::files/read::{"path":"~/code/README.md"}
 834-    ```
 835-
 836-多行命令:
 837-
 838-    ```baa
 839-    @conductor::exec
 840-    cd ~/code/baa-conductor
 841-    npm test
 842-    ```
 843-
 844-执行结果会自动回传(小结果文本注入,大结果文件上传),继续分析即可。
 845+```baa
 846+@browser.claude::send::请总结上一轮执行结果
 847 ```
 848 
 849----
 850-
 851-## 14. 渐进式落地阶段
 852-
 853-### Phase 0:冻结语法
 854-
 855-确认语法规范,生成通用 prompt 模板,验证三个平台都能稳定输出 ` ```baa `。
 856-
 857-### Phase 1:conductor 解析中心 + 薄插件
 858-
 859-插件加一行 wsSend 转发完整回复。conductor 新增 instructions/ 模块(extract → parse → route → execute → delivery plan)。先跑通 Claude 链路:能稳定自动执行 3~5 轮,不重复执行,用户输入能打断,失败会熔断。
 860-
 861-### Phase 2:artifact 交付
 862+## 9. 设计分层
 863 
 864-大结果产物化 + manifest + 文件上传 + upload receipt barrier + 索引文本。上传成功后才发索引。多结果并行时 manifest 稳定。
 865+当前应按下面这组文档理解:
 866 
 867-### Phase 3:ChatGPT / Gemini 正式接入
 868-
 869-`/v1/browser/chatgpt/*` + `/v1/browser/gemini/*` 正式 surface。验收:Claude 能借 ChatGPT 生图,ChatGPT 能借 conductor 做 shell。
 870-
 871-### Phase 4:能力池与角色池
 872-
 873-pool.image / pool.video / pool.exec / role.reviewer / role.coder。验收:`@pool.image::generate` 能自动选可用节点。
 874-
 875-### Phase 5:多 AI 自洽协作层
 876-
 877-round / chain / gossip / consensus 纳入统一编排。
 878-
 879-### Phase 6:任务池与后台长流程
 880-
 881-task/create + task/poll,复杂流程不再挤在一个聊天轮次里。
 882-
 883-### 每阶段回归项
 884-
 885-- 不解析普通代码块
 886-- 不在 streaming 半截执行
 887-- 不重复执行同一块
 888-- 用户输入能抢占
 889-- pause / resume / drain 稳定
 890-- 结果不泄露敏感信息
 891-- 上传 / 下载失败能重试或降级
 892-
 893----
 894-
 895-## 15. 直接可用示例
 896-
 897-### 本机操作
 898-
 899-    ```baa
 900-    @conductor::exec::ls ~/code
 901-    ```
 902-
 903-    ```baa
 904-    @conductor::files/read::{"path":"~/Desktop/HANDOFF.md"}
 905-    ```
 906-
 907-    ```baa
 908-    @conductor::exec
 909-    cd ~/code/baa-conductor
 910-    pnpm test
 911-    ```
 912-
 913-### 能力借用
 914-
 915-    ```baa
 916-    @browser.chatgpt::send::请生成一张赛博朋克风格城市夜景图
 917-    ```
 918-
 919-    ```baa
 920-    @browser.gemini::send::请生成一段 5 秒的视频:一只猫在键盘上打字
 921-    ```
 922-
 923-### 系统管理
 924-
 925-    ```baa
 926-    @conductor::describe
 927-    ```
 928-
 929-    ```baa
 930-    @conductor::browser/actions::{"action":"plugin_status"}
 931-    ```
 932-
 933----
 934-
 935-## 附录 A:TypeScript 类型定义
 936-
 937-```typescript
 938-export type RiskTier = "tier0" | "tier1" | "tier2" | "tier3";
 939-export type DeliveryMode = "inline" | "inline_and_artifact" | "artifact_only";
 940-
 941-export interface ParsedBaaInstruction {
 942-  rawBlock: string;
 943-  blockIndex: number;
 944-  target: string;
 945-  tool: string;
 946-  params: Record<string, unknown>;
 947-}
 948-
 949-export interface NormalizedInstruction extends ParsedBaaInstruction {
 950-  instructionId: string;
 951-  traceId: string;
 952-  conversationId: string | null;
 953-  assistantMessageId: string | null;
 954-  sourceNode: string;
 955-  roundId: string | null;
 956-  hop: number;
 957-  riskTier: RiskTier;
 958-  dedupeKey: string;
 959-  createdAt: number;
 960-}
 961-
 962-export interface RouteDecision {
 963-  resolvedTarget: string;
 964-  resolvedNodeId?: string;
 965-  routeReason: string[];
 966-  fallbackCandidates: string[];
 967-}
 968-
 969-export interface ArtifactRef {
 970-  artifactId: string;
 971-  kind: "summary" | "payload" | "manifest" | "preview" | "log" | "image" | "video" | "other";
 972-  filename: string;
 973-  mimeType: string;
 974-  sizeBytes?: number;
 975-  sha256?: string;
 976-  localPath?: string;
 977-  remoteHandle?: string | null;
 978-}
 979-
 980-export interface ExecutionResult {
 981-  instructionId: string;
 982-  ok: boolean;
 983-  target: string;
 984-  tool: string;
 985-  summary: string;
 986-  data?: unknown;
 987-  truncated?: boolean;
 988-  deliveryMode: DeliveryMode;
 989-  artifactRefs?: ArtifactRef[];
 990-  errorCode?: string;
 991-}
 992-
 993-export interface DeliveryUploadItem {
 994-  artifactId: string;
 995-  filename: string;
 996-  mimeType: string;
 997-  localPath: string;
 998-}
 999-
1000-export interface DeliveryPlan {
1001-  planId: string;
1002-  traceId: string;
1003-  conversationId: string | null;
1004-  target: string;
1005-  uploads: DeliveryUploadItem[];
1006-  messageText: string;
1007-  autoSend: boolean;
1008-}
1009-
1010-export interface UploadReceipt {
1011-  artifactId: string;
1012-  ok: boolean;
1013-  remoteHandle?: string;
1014-  errorCode?: string;
1015-}
1016-
1017-export interface DownloadPlan {
1018-  downloadPlanId: string;
1019-  items: Array<{
1020-    remoteHandle: string;
1021-    suggestedFilename: string;
1022-    savePath: string;
1023-  }>;
1024-}
1025-```
1026-
1027-## 附录 B:结果交付决策伪代码
1028-
1029-```javascript
1030-async function deliverResults(platform, results, wsChannel) {
1031-  // conductor 侧决策
1032-  const artifacts = materializeArtifacts(results);
1033-  const manifest = buildManifest(results, artifacts);
1034-  const plan = buildDeliveryPlan(results, artifacts, manifest);
1035-
1036-  // 通过 WS 指示插件执行
1037-  wsChannel.send({ type: "delivery_plan", plan });
1038-
1039-  // 等待插件上传确认
1040-  const receipts = await waitForUploadReceipts(plan.uploads, { timeoutMs: 30000 });
1041-  const allUploaded = receipts.every(r => r.ok);
1042-
1043-  if (!allUploaded) {
1044-    // 降级:未上传成功的改为截断文本
1045-    const degradedText = formatDegradedTextResults(results, receipts);
1046-    wsChannel.send({ type: "inject_text", text: degradedText, autoSend: true });
1047-    return;
1048-  }
1049-
1050-  // 全部上传成功,发送索引文本
1051-  const indexText = renderIndexText(results, manifest);
1052-  wsChannel.send({ type: "inject_text", text: indexText, autoSend: plan.autoSend });
1053-}
1054-```
1055+- [`./BAA_INSTRUCTION_SYSTEM.md`](./BAA_INSTRUCTION_SYSTEM.md):当前正式合同
1056+- [`./BAA_INSTRUCTION_ROADMAP.md`](./BAA_INSTRUCTION_ROADMAP.md):未来目标与扩展方向
1057+- [`./STATUS_SUMMARY.md`](./STATUS_SUMMARY.md):当前主线状态与优先级
1058+- [`./archive/BAA_BROWSER_PROXY_DELIVERY_REQUIREMENTS.md`](./archive/BAA_BROWSER_PROXY_DELIVERY_REQUIREMENTS.md):本轮 proxy-first delivery 收口记录
M plans/STATUS_SUMMARY.md
+4, -4
 1@@ -6,7 +6,7 @@
 2 
 3 ## 当前代码基线
 4 
 5-- 当前主分支:`main`(已包含 `6b819bf`、`6e458f3`、`978aa4c`)
 6+- 当前主分支:`main@8ef82d8`
 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@@ -29,8 +29,8 @@
11 ## 当前已纠正的文档/代码不一致
12 
13 - `T-S037` 之前仍作为 active task 留在根目录,但代码已经合入;现在已归档
14-- `BAA_INSTRUCTION_SYSTEM.md` 之前把 upload / download 写成当前插件职责,也把 `browser.chatgpt` / `browser.gemini` 写成了像是当前已支持 target;现在已补充“当前实现 vs 规划目标”的区分
15-- `BAA_PLUGIN_DELIVERY_HARDENING_REQUIREMENTS.md` 现在只保留为 DOM fallback 历史方案,不再代表当前主线架构方向
16+- `BAA_INSTRUCTION_SYSTEM.md` 现在只保留当前正式合同;未来目标已拆到 `BAA_INSTRUCTION_ROADMAP.md`
17+- `BAA_PLUGIN_DELIVERY_HARDENING_REQUIREMENTS.md` 已移到 `archive/`,不再停留在根目录制造“仍是当前主线”的错觉
18 - `BUG-024` / `BUG-025` 已完成并归档,不再作为 open blocker 挂在 backlog
19 
20 ## 当前最高优先级
21@@ -54,11 +54,11 @@
22 ## 当前活跃需求文档
23 
24 - [`./BAA_INSTRUCTION_SYSTEM.md`](./BAA_INSTRUCTION_SYSTEM.md)
25+- [`./BAA_INSTRUCTION_ROADMAP.md`](./BAA_INSTRUCTION_ROADMAP.md)
26 - [`./STATUS_SUMMARY.md`](./STATUS_SUMMARY.md)
27 
28 保留在根目录但不是当前主线目标的历史文档:
29 
30-- [`./BAA_PLUGIN_DELIVERY_HARDENING_REQUIREMENTS.md`](./BAA_PLUGIN_DELIVERY_HARDENING_REQUIREMENTS.md)
31 - [`./BAA_ARTIFACT_DOWNLOAD_REQUIREMENTS.md`](./BAA_ARTIFACT_DOWNLOAD_REQUIREMENTS.md)
32 
33 ## 当前主线判断
M plans/archive/BAA_BROWSER_PROXY_DELIVERY_REQUIREMENTS.md
+1, -0
1@@ -9,6 +9,7 @@
2 ## 关联文档
3 
4 - [BAA_INSTRUCTION_SYSTEM.md](../BAA_INSTRUCTION_SYSTEM.md)
5+- [BAA_INSTRUCTION_ROADMAP.md](../BAA_INSTRUCTION_ROADMAP.md)
6 - [STATUS_SUMMARY.md](../STATUS_SUMMARY.md)
7 - [plugins/baa-firefox/README.md](../../plugins/baa-firefox/README.md)
8 - [BUG-025-chatgpt-delivery-targets-shell-page.md](../../bugs/archive/BUG-025-chatgpt-delivery-targets-shell-page.md)
A plans/archive/BAA_PLUGIN_DELIVERY_HARDENING_REQUIREMENTS.md
+83, -0
 1@@ -0,0 +1,83 @@
 2+# BAA 插件侧 Delivery 加固需求
 3+
 4+## 状态
 5+
 6+- `已归档(T-S035,2026-03-28)`
 7+- `当前只保留为 DOM fallback 历史方案;代理式主链已在 ./BAA_BROWSER_PROXY_DELIVERY_REQUIREMENTS.md 完成`
 8+- 优先级:`high`
 9+- 记录时间:`2026-03-27`
10+
11+## 关联文档
12+
13+- [BAA_DELIVERY_BRIDGE_REQUIREMENTS.md](./BAA_DELIVERY_BRIDGE_REQUIREMENTS.md)
14+- [BAA_ARTIFACT_CENTER_REQUIREMENTS.md](./BAA_ARTIFACT_CENTER_REQUIREMENTS.md)
15+- [../BAA_INSTRUCTION_SYSTEM.md](../BAA_INSTRUCTION_SYSTEM.md)
16+- [../BAA_INSTRUCTION_ROADMAP.md](../BAA_INSTRUCTION_ROADMAP.md)
17+- [../../docs/firefox/README.md](../../docs/firefox/README.md)
18+
19+## 背景
20+
21+当前 live delivery 已经收口到:
22+
23+- `browser.inject_message`
24+- `browser.send_message`
25+
26+但当前插件侧交付仍保留 3 个直接风险:
27+
28+- inject / send 仍主要依赖 DOM heuristic
29+- 首版只对 `Claude` / `ChatGPT` 做了选择器与流程
30+- 失败恢复、页面 readiness 和平台差异当前还不够收口
31+
32+这意味着当前链路虽然可用,但平台页面稍有结构变化,就可能把交付稳定性重新打回“脆弱自动化”。
33+
34+## 核心结论
35+
36+- 插件仍保持 thin-plugin 方向,不在插件里做 artifact 打包、parser 或复杂编排
37+- 下一步应把 delivery 逻辑显式收口为平台 adapter,而不是继续散落在通用 DOM heuristic 里
38+- 首批只加固:
39+  - `Claude`
40+  - `ChatGPT`
41+- 加固重点是:
42+  - readiness 探测
43+  - 平台选择器集中管理
44+  - 失败重试 / fail-closed
45+  - 结构化状态与错误回写
46+
47+## 范围
48+
49+- `Claude` / `ChatGPT` 平台 delivery adapter 收口
50+- text-only `inject / send` readiness 探测与超时
51+- 结构化失败原因、平台状态和调试字段
52+- browser smoke 与文档回写
53+
54+## 当前明确不要求
55+
56+- 不要求在本需求里扩到 `Gemini`
57+- 不要求在本需求里恢复 upload / download / binary delivery
58+- 不要求在本需求里扩到多客户端、多轮 delivery
59+- 不要求在本需求里改 task/run 编排或跨节点分发
60+
61+## 验收条件
62+
63+- `Claude` / `ChatGPT` 的 text-only `inject / send` 逻辑有明确 adapter 边界,不再散落为隐式 heuristic
64+- 页面未 ready、选择器失效、发送失败时会返回明确错误,不会静默成功
65+- browser smoke 能覆盖至少一条成功路径和一条 fail-closed 路径
66+- 文档已同步到 `plans/`、`tasks/`、`docs/firefox/` 和必要的 `docs/api/`
67+
68+## 当前预期残余边界
69+
70+- 插件侧最终仍会依赖 DOM / 页面结构,只是把风险收口成可维护的 adapter 层
71+- 首版仍只覆盖 `Claude` / `ChatGPT`
72+- 当前仍只服务于单客户端、单轮 delivery
73+
74+## 完成回写(2026-03-27)
75+
76+- 已完成:
77+  - Firefox 插件 content script 已新增独立 `delivery-adapters.js`,把 `Claude` / `ChatGPT` 的 text-only `inject / send` 统一收口到 adapter 边界
78+  - adapter 已补 page readiness、selector 解析、发送确认和有限重试;失败时返回稳定 `delivery.<code>` 错误并 fail-closed
79+  - 插件侧不再接受 `upload_artifact` 命令
80+  - browser smoke 已覆盖 adapter 成功路径、page-not-ready 和 send-not-confirmed 失败路径
81+- 当前残余边界:
82+  - 仍然依赖 DOM / 页面结构,只是风险已集中在 adapter 模块
83+  - 仍未扩到 `Gemini`
84+  - 当前仍只服务于单客户端、单轮 delivery
M plans/archive/README.md
+2, -1
 1@@ -15,11 +15,12 @@
 2 - [`BAA_ARTIFACT_CENTER_REQUIREMENTS.md`](./BAA_ARTIFACT_CENTER_REQUIREMENTS.md):已完成,对应 `T-S032`
 3 - [`BAA_EXECUTION_PERSISTENCE_REQUIREMENTS.md`](./BAA_EXECUTION_PERSISTENCE_REQUIREMENTS.md):已完成,对应 `T-S033`
 4 - [`BAA_DELIVERY_BRIDGE_REQUIREMENTS.md`](./BAA_DELIVERY_BRIDGE_REQUIREMENTS.md):已完成,对应 `T-S034`
 5+- [`BAA_PLUGIN_DELIVERY_HARDENING_REQUIREMENTS.md`](./BAA_PLUGIN_DELIVERY_HARDENING_REQUIREMENTS.md):已完成,对应 `T-S035`
 6 - [`BAA_BROWSER_PROXY_DELIVERY_REQUIREMENTS.md`](./BAA_BROWSER_PROXY_DELIVERY_REQUIREMENTS.md):已完成,对应 `T-S038`
 7 
 8 ## 当前仍在根目录的需求文档
 9 
10 - [`../BAA_INSTRUCTION_SYSTEM.md`](../BAA_INSTRUCTION_SYSTEM.md)
11+- [`../BAA_INSTRUCTION_ROADMAP.md`](../BAA_INSTRUCTION_ROADMAP.md)
12 - [`../STATUS_SUMMARY.md`](../STATUS_SUMMARY.md)
13-- [`../BAA_PLUGIN_DELIVERY_HARDENING_REQUIREMENTS.md`](../BAA_PLUGIN_DELIVERY_HARDENING_REQUIREMENTS.md):已完成,当前只作为 DOM fallback 历史方案
14 - [`../BAA_ARTIFACT_DOWNLOAD_REQUIREMENTS.md`](../BAA_ARTIFACT_DOWNLOAD_REQUIREMENTS.md):已废弃,当前只保留历史决策说明
M tasks/TASK_OVERVIEW.md
+4, -3
 1@@ -3,7 +3,7 @@
 2 ## 当前基线
 3 
 4 - 日期:`2026-03-28`
 5-- 主分支基线:`main`(已包含 `6b819bf`、`6e458f3`、`978aa4c`)
 6+- 主分支基线:`main@8ef82d8`
 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@@ -27,7 +27,8 @@
11 这轮整理后,下面几处旧口径已经被显式改正:
12 
13 - `T-S037` 之前仍挂在根目录作为 active task,但代码已经合入 `main`;现在已归档
14-- `plans/BAA_INSTRUCTION_SYSTEM.md` 之前把 upload / download 写成当前插件职责,也把 `browser.chatgpt` / `browser.gemini` 写得像当前已支持 target;现在已补充“当前实现 vs 规划目标”的区分
15+- `plans/BAA_INSTRUCTION_SYSTEM.md` 现在只保留当前正式合同;未来目标已拆到 `plans/BAA_INSTRUCTION_ROADMAP.md`
16+- `plans/archive/BAA_PLUGIN_DELIVERY_HARDENING_REQUIREMENTS.md` 已移入 archive,不再停留在根目录误导成 current plan
17 - `BUG-024` / `BUG-025` 已经分别随 `6b819bf` 和 `6e458f3` 收口,不再作为 open bug 保留在根目录索引
18 
19 ## 当前活跃任务与优先级
20@@ -57,11 +58,11 @@
21 ## 当前活跃需求文档
22 
23 - [`../plans/BAA_INSTRUCTION_SYSTEM.md`](../plans/BAA_INSTRUCTION_SYSTEM.md)
24+- [`../plans/BAA_INSTRUCTION_ROADMAP.md`](../plans/BAA_INSTRUCTION_ROADMAP.md)
25 - [`../plans/STATUS_SUMMARY.md`](../plans/STATUS_SUMMARY.md)
26 
27 保留在根目录但不再作为当前主线目标的历史文档:
28 
29-- [`../plans/BAA_PLUGIN_DELIVERY_HARDENING_REQUIREMENTS.md`](../plans/BAA_PLUGIN_DELIVERY_HARDENING_REQUIREMENTS.md):已完成,当前只作为 DOM fallback 历史说明
30 - [`../plans/BAA_ARTIFACT_DOWNLOAD_REQUIREMENTS.md`](../plans/BAA_ARTIFACT_DOWNLOAD_REQUIREMENTS.md):已废弃,保留历史决策说明
31 
32 ## 当前主线判断
M tasks/archive/T-S035.md
+2, -2
 1@@ -2,11 +2,11 @@
 2 
 3 ## 直接给对话的提示词
 4 
 5-读 `/Users/george/code/baa-conductor/tasks/T-S035.md` 任务文档,完成开发任务。
 6+读 `/Users/george/code/baa-conductor/tasks/archive/T-S035.md` 任务文档,查看已完成任务记录。
 7 
 8 如需补背景,再读:
 9 
10-- `/Users/george/code/baa-conductor/plans/BAA_PLUGIN_DELIVERY_HARDENING_REQUIREMENTS.md`
11+- `/Users/george/code/baa-conductor/plans/archive/BAA_PLUGIN_DELIVERY_HARDENING_REQUIREMENTS.md`
12 - `/Users/george/code/baa-conductor/plans/archive/BAA_DELIVERY_BRIDGE_REQUIREMENTS.md`
13 - `/Users/george/code/baa-conductor/docs/firefox/README.md`
14