diff --git a/docs/reports/2026-04-18-browser-mcp-phase6-design.md b/docs/reports/2026-04-18-browser-mcp-phase6-design.md
deleted file mode 100644
index 3763c1b5..00000000
--- a/docs/reports/2026-04-18-browser-mcp-phase6-design.md
+++ /dev/null
@@ -1,272 +0,0 @@
-# Browser MCP Phase 6 Design
-
-Last Updated: 2026-04-18
-
-## Goal
-
-在 `feat/browser-mcp-hover-phase6` worktree 中,为 CCS-managed `ccs-browser` MCP runtime 设计 Browser MCP Phase 6。
-本阶段延续既有 browser MCP 能力蓝图,优先聚焦 network interception / mock responses,并保持 Phase 1-5 一致的最小增量策略。
-
-Phase 6 不在当前阶段一次性做完整网络代理层,而是拆成两个连续子阶段:
-
-- **Phase 6A**:request observation + scoped interception skeleton
-- **Phase 6B**:mock responses
-
-## Scope Summary
-
-### In Scope for Phase 6A
-
-- 新增会话级 interception rule 管理能力
-- 新增近期请求摘要查看能力
-- 基于目标页建立 Fetch interception 会话
-- 支持最小匹配集:`urlIncludes`、`method`
-- 支持最小动作集:`continue`、`fail`
-- 维持 session-local state,不做跨 runtime 重启持久化
-
-### Deferred to Phase 6B
-
-- `fulfill` / mock response action
-- 自定义 status / headers / body
-- response body 编码与更复杂序列化
-- 更复杂的匹配条件,如资源类型、headers、正则、优先级
-- 浏览器级或跨页共享拦截规则
-
-## Architecture
-
-Phase 6 继续沿用现有 `lib/mcp/ccs-browser-server.cjs` 单 runtime 架构,不额外引入第二套 browser server,也不改写当前页面选择与工具注册模型。
-
-现有 runtime 已具备两类基础能力:
-
-- 页面级 CDP 请求发送:`sendCdpCommand(page, method, params)`
-- 事件型 websocket 监听:当前 `browser_wait_for_event` 已能在页级 websocket 上启用 `Page.enable` / `Network.enable`
-
-Phase 6 在这一基础上增加一层 **session-local interception state**,而不是引入新的全局配置层。
-
-整体结构分为三层:
-
-1. **Tool surface**:新增规则管理和请求查看工具
-2. **Session-local state**:记录规则、近期请求和页级 interception session
-3. **Page interception session**:在具体 page target 上维护 Fetch domain 长连接,处理 paused requests
-
-## Tool Surface
-
-Phase 6A 先只新增四个工具,形成最小闭环。
-
-### `browser_add_intercept_rule`
-
-为某个页面添加一条会话级拦截规则。
-
-建议参数:
-
-- `pageIndex?: number`
-- `pageId?: string`
-- `urlIncludes?: string`
-- `method?: string`
-- `action: "continue" | "fail"`
-
-行为:
-
-- 如果省略 `pageIndex/pageId`,按调用当下的 selected page 解析一次目标页
-- 解析结果固化为具体 `pageId`
-- 创建 ruleId 并返回
-- 若目标页尚未建立 interception session,则启动该页的 Fetch interception 长连接
-
-### `browser_remove_intercept_rule`
-
-按 `ruleId` 删除一条规则。
-
-建议参数:
-
-- `ruleId: string`
-
-行为:
-
-- 删除对应规则
-- 如果某页已无任何规则,回收该页 interception session
-
-### `browser_list_intercept_rules`
-
-列出当前 MCP runtime 内存中的有效规则。
-
-返回字段最小化,建议包含:
-
-- `ruleId`
-- `pageId`
-- `pageTitle`
-- `urlIncludes`
-- `method`
-- `action`
-
-### `browser_list_requests`
-
-返回近期观测到的请求摘要。
-
-建议参数:
-
-- `pageIndex?: number`
-- `pageId?: string`
-- `limit?: number`
-
-返回字段最小化,建议包含:
-
-- `requestId`
-- `pageId`
-- `url`
-- `method`
-- `resourceType`
-- `matchedRuleId`
-- `action`
-
-## State Model
-
-Phase 6A 在 runtime 内维护三块 session-local 状态:
-
-### `interceptRules`
-
-存储当前有效规则列表。每条规则至少包含:
-
-- `ruleId`
-- `pageId`
-- `pageTitleSnapshot`
-- `urlIncludes`
-- `method`
-- `action`
-- `createdAt`
-
-关键约束:
-
-- 规则绑定到**创建时解析出的具体 pageId**
-- 规则不会在后续切换 selected page 时自动漂移
-- 规则不持久化到磁盘
-
-### `recentRequests`
-
-存储近期请求摘要,供 `browser_list_requests` 使用。
-
-关键约束:
-
-- 固定上限,建议 100 条
-- 超过上限时丢弃最旧记录
-- 只保留摘要,不保留 body
-
-### `interceptSessionsByPageId`
-
-存储每个被拦截页面对应的长连接会话。
-
-每个 session 至少需要管理:
-
-- `pageId`
-- `webSocketDebuggerUrl`
-- websocket 实例
-- 当前是否已启用 `Fetch.enable`
-- 关联规则数量
-- 最近错误状态(如果需要)
-
-## Data Flow
-
-### Add Rule Flow
-
-1. `browser_add_intercept_rule` 解析目标页
-2. 校验参数与最小匹配条件
-3. 生成 `ruleId`
-4. 将规则写入 `interceptRules`
-5. 为目标页创建或复用 interception session
-6. 在该页 websocket 上启用 `Fetch.enable`
-7. 返回 rule 摘要
-
-### Request Interception Flow
-
-1. 页级 interception session 收到 paused request 事件
-2. 从该页规则中按创建顺序依次匹配
-3. 第一条命中规则决定动作
-4. 执行动作:
- - `continue` -> 放行请求
- - `fail` -> 以固定错误原因中止请求
-5. 写入 `recentRequests`
-6. 若无命中规则,则默认 `continue`
-
-### Remove Rule Flow
-
-1. `browser_remove_intercept_rule` 按 `ruleId` 找到规则
-2. 从 `interceptRules` 删除
-3. 若规则所属页已无剩余规则,则关闭该页 interception session
-4. 返回删除结果
-
-### List Requests Flow
-
-1. `browser_list_requests` 按可选 page filter 过滤
-2. 按时间倒序返回近期摘要
-3. 应用 `limit`
-
-## Error Handling and Boundary Rules
-
-### Parameter Rules
-
-`browser_add_intercept_rule`:
-
-- `pageIndex` 和 `pageId` 不能同时传
-- `action` 只能是 `continue` 或 `fail`
-- 至少要有一个匹配条件:`urlIncludes` 或 `method`
-- 目标页不存在、已关闭或无 websocket target 时直接报错
-
-`browser_remove_intercept_rule`:
-
-- `ruleId` 不存在时报错
-
-`browser_list_requests`:
-
-- `pageIndex` 和 `pageId` 不能同时传
-- `limit` 越界时回退到安全默认值
-
-### Lifecycle Rules
-
-- 所有 interception 规则都是 session-local in-memory state
-- 目标页关闭后,该页规则自动失效并从规则列表中清除
-- `browser_list_intercept_rules` 只返回当前仍有效的规则
-- runtime 重启后,所有规则和请求摘要都会丢失
-
-### Concurrency Rules
-
-- 规则管理工具继续沿用当前 runtime 的串行消息语义,避免状态竞态
-- 真正的请求拦截事件在页级长连接中异步处理
-- 页级拦截事件只允许修改自身 pageId 对应的 interception session 状态,以及共享的 `recentRequests`
-
-## Interaction with Existing Phase 5 State
-
-Phase 6 必须与现有 selected page 语义兼容:
-
-- 添加规则时若省略目标页参数,只在创建当下读取 selected page 一次
-- 规则创建完成后绑定到具体 pageId,不再受后续切页影响
-- `browser_select_page`、`browser_open_page`、`browser_close_page` 不直接重写既有规则的 page binding
-- 如果 `browser_close_page` 关闭了被规则绑定的页面,相关规则应自动清理
-
-## Testing Strategy
-
-Phase 6A 测试应继续扩展 `tests/unit/hooks/ccs-browser-mcp-server.test.ts` 里的 deterministic harness。
-
-最小测试集建议覆盖:
-
-1. 工具列表与 schema 暴露正确
-2. 添加规则后能在规则列表中看到
-3. 删除规则后规则消失
-4. 两条规则按创建顺序匹配,先命中者生效
-5. 省略 `pageIndex/pageId` 时按当前 selected page 绑定
-6. 切换 selected page 后,旧规则仍绑定原 pageId
-7. 关闭绑定页面后规则自动清理
-8. `browser_list_requests` 只返回摘要并 obey `limit`
-9. 无命中规则时默认 continue
-10. `fail` 动作能生成稳定且可断言的结果
-
-## Why This Split
-
-将 Phase 6 拆成 6A / 6B 的原因是:
-
-- 先稳定规则管理、页级会话和 paused request 生命周期
-- 再叠加 mock fulfill response,避免一开始把匹配、状态管理、headers/body 序列化全耦合到一起
-- 与 Phase 1-5 的最小闭环推进方式保持一致
-
-6A 解决的是“能稳定地拦住并控制请求”;6B 再解决“能把响应内容完全替换掉”。
-
-## Out of Scope in This Design Pass
-
-本轮设计确认只覆盖 Phase 6 的拆分方式与 6A 的最小闭环,不直接进入 6B 的详细实现步骤,也不在这里展开 implementation plan。
diff --git a/docs/reports/2026-04-18-browser-mcp-phase7-design.md b/docs/reports/2026-04-18-browser-mcp-phase7-design.md
deleted file mode 100644
index 73ab8d82..00000000
--- a/docs/reports/2026-04-18-browser-mcp-phase7-design.md
+++ /dev/null
@@ -1,323 +0,0 @@
-# Browser MCP Phase 7 Design
-
-Last Updated: 2026-04-18
-
-## Goal
-
-在新的 `feat/browser-mcp-hover-phase7` worktree 中,为 CCS-managed `ccs-browser` MCP runtime 设计 Browser MCP Phase 7。
-本阶段延续 Phase 6 的 network interception 路线,优先聚焦 **richer request matching**,让现有拦截规则可以按更细的请求特征命中,同时保持既有最小增量策略。
-
-## Scope Summary
-
-### In Scope
-
-- 在现有 `browser_add_intercept_rule` 基础上扩展更丰富的匹配条件
-- 新增最小匹配维度:
- - `resourceType`
- - `urlPattern` 或 `urlRegex`(二选一)
- - `headerMatchers`
- - `priority`
-- 将规则匹配顺序从“创建顺序”扩展为:
- 1. `priority` 从高到低
- 2. 同优先级按创建顺序
-- 扩展 `browser_list_intercept_rules` 输出,展示新增匹配摘要
-- 保持 `browser_list_requests` 为请求摘要视图,不输出 request/response body
-- 保持 selected page 解析语义、规则绑定具体 `pageId`、session-local runtime state、页级 websocket interception session 与 `messageQueue` 串行语义
-
-### Explicitly Out of Scope
-
-- 跨页共享规则或浏览器级全局规则
-- 下载接受/拒绝控制与下载文件管理
-- 请求体匹配
-- 响应阶段匹配
-- 更复杂布尔逻辑(如任意/全部组、嵌套条件、否定条件)
-- 完整网络代理层
-
-## Why Phase 7 Follows Phase 6
-
-Phase 6 已建立:
-
-- page-bound 的 interception rule 管理面
-- session-local `interceptRules` / `recentRequests` / `interceptSessionsByPageId`
-- `continue` / `fail` / `fulfill` 三种最小动作集
-
-历史设计里也已明确把以下能力延后到后续阶段:
-
-- 更复杂的匹配条件,如 `resourceType`、`headerMatchers`、正则、优先级
-- 跨页共享规则
-- 下载接受控制
-
-因此,Phase 7 继续沿 network interception 主线推进 richer matching,是与现有实现最连续、收益最大的下一阶段;它能显著提升规则可用性,同时不会把作用域和下载控制这两类新问题混进同一期。
-
-## Architecture
-
-Phase 7 继续沿用 `lib/mcp/ccs-browser-server.cjs` 的单 runtime 架构,不引入新的 browser runtime,也不改写 Phase 5 的 selected page 模型和 Phase 6 的 interception session 生命周期。
-
-本阶段仍沿用三层结构:
-
-1. **Tool surface**:复用现有四个 interception 相关工具,只扩展参数与输出摘要
-2. **Session-local state**:继续复用 `interceptRules`、`recentRequests`、`interceptSessionsByPageId`
-3. **Page interception session**:继续由具体 page target 的 websocket 消费 paused requests,并根据 richer matching 结果执行动作
-
-关键设计约束:
-
-- 规则仍在创建时解析并固化为具体 `pageId`
-- 规则不会在后续 selected page 切换时自动漂移
-- 新增 richer matching 不改变现有 action 执行路径,只改变“哪条规则命中”
-- `messageQueue` 继续只负责工具入口串行语义;页级 websocket 仍异步接收 paused request 事件
-
-## Tool Surface
-
-Phase 7 不新增新工具,继续复用:
-
-- `browser_add_intercept_rule`
-- `browser_remove_intercept_rule`
-- `browser_list_intercept_rules`
-- `browser_list_requests`
-
-### `browser_add_intercept_rule`
-
-在 Phase 6 参数基础上,扩展最小 richer matching 参数:
-
-- `pageIndex?: number`
-- `pageId?: string`
-- `urlIncludes?: string`
-- `method?: string`
-- `resourceType?: string`
-- `urlPattern?: string`
-- `urlRegex?: string`
-- `headerMatchers?: Array<{ name: string; valueIncludes?: string; valueRegex?: string }>`
-- `priority?: number`
-- `action: "continue" | "fail" | "fulfill"`
-- `statusCode?`, `contentType?`, `responseHeaders?`, `body?`(仅 `action: "fulfill"` 时沿用 Phase 6B 现有语义;避免与请求匹配用的 `headerMatchers` 混淆)
-
-约束:
-
-- `pageIndex` 与 `pageId` 不能同时传
-- `urlPattern` 与 `urlRegex` 不能同时传
-- `priority` 默认 `0`
-- `priority` 必须是整数
-- header matcher 的 `name` 必填
-- 每个 header matcher 至少需要一个值条件:`valueIncludes` 或 `valueRegex`
-- Phase 7 仍要求至少有一个请求匹配条件,避免创建“无条件全匹配”规则
-
-### `browser_remove_intercept_rule`
-
-保持不变,仅按 `ruleId` 删除对应规则。
-
-### `browser_list_intercept_rules`
-
-在现有输出基础上,新增简洁摘要字段:
-
-- `priority`
-- `resourceType`
-- `urlPattern` 或 `urlRegex`
-- `headerMatchers` 条件数量或简写摘要
-
-要求:
-
-- 仍保持文本摘要可读性
-- 不直接把长正则或大量 header 条件原样完整展开到难以阅读
-
-### `browser_list_requests`
-
-保持“近期请求摘要”定位,不展示 request/response body。
-
-可选补充字段:
-
-- `matchedRuleId`
-- `action`
-- `statusCode`(仅 fulfill)
-- 必要时增加一个轻量命中说明,如 `matchedBy`,只表示命中依赖了哪类条件,不重复整条规则
-
-## State Model
-
-Phase 7 仍复用 Phase 6 的三块 session-local 状态。
-
-### `interceptRules`
-
-每条规则在 Phase 6 基础上新增:
-
-- `resourceType`
-- `urlPattern`
-- `urlRegex`
-- `headerMatchers`
-- `priority`
-
-关键约束:
-
-- 规则绑定到创建时解析出的具体 `pageId`
-- 规则仍不持久化到磁盘
-- `priority` 仅影响匹配顺序,不影响工具展示或生命周期清理逻辑
-
-### `recentRequests`
-
-仍然只存储近期请求摘要,继续不保留 body。
-
-如增加 `matchedBy`,也只记录轻量摘要,而不是完整匹配细节。
-
-### `interceptSessionsByPageId`
-
-不新增新的 session 级状态表。
-
-Phase 7 只扩匹配逻辑,不改 websocket 生命周期模型:
-
-- 规则创建时按需建立 session
-- 页面关闭或无规则时回收 session
-- websocket 断开时继续进行现有清理与错误恢复语义
-
-## Matching Model
-
-### Matching Order
-
-对某个 paused request,只在其所属 `pageId` 的规则集合内匹配。
-
-匹配顺序:
-
-1. `priority` 从高到低
-2. 同优先级按创建顺序
-3. 第一条完整命中的规则生效
-
-这意味着 Phase 7 解决了 Phase 6 “只能按创建顺序命中”的限制,同时避免引入更复杂的规则编排系统。
-
-### Rule Predicate Evaluation
-
-每条规则依次检查:
-
-1. `method`
-2. `urlIncludes`
-3. `urlPattern` 或 `urlRegex`
-4. `resourceType`
-5. `headerMatchers`
-
-所有已提供条件都必须命中,规则才算匹配成功。
-
-### Header Matching
-
-Phase 7 的 header matching 采用最小规则:
-
-- header 名称按大小写不敏感匹配
-- 每个 matcher 至少要求一个值条件:
- - `valueIncludes`
- - `valueRegex`
-- 多个 header matcher 之间采用“全部满足”语义
-
-Phase 7 不支持:
-
-- any/all 模式切换
-- header 多值数组高级语义
-- 负向匹配
-- body/JSON 级内容匹配
-
-## Data Flow
-
-### Add Rule Flow
-
-1. `browser_add_intercept_rule` 解析目标页
-2. 校验 richer matching 参数
-3. 生成 `ruleId`
-4. 将规则写入 `interceptRules`
-5. 为目标页创建或复用 interception session
-6. 返回包含新增匹配摘要的 rule 文本
-
-### Request Match Flow
-
-1. 页级 interception session 收到 paused request 事件
-2. 取出该页全部有效规则
-3. 按 `priority DESC + createdAt ASC` 排序
-4. 逐条检查 method / URL / resourceType / `headerMatchers` 条件
-5. 第一条命中规则决定 action:
- - `continue`
- - `fail`
- - `fulfill`
-6. 将结果写入 `recentRequests`
-7. 若无任何规则命中,则默认 `continue`
-
-### Remove Rule Flow
-
-保持 Phase 6 行为:
-
-1. `browser_remove_intercept_rule` 按 `ruleId` 找到规则
-2. 从 `interceptRules` 删除
-3. 若该页已无剩余规则,则关闭该页 interception session
-4. 返回删除结果
-
-## Error Handling and Boundary Rules
-
-### Parameter Rules
-
-`browser_add_intercept_rule`:
-
-- `pageIndex` 和 `pageId` 不能同时传
-- `urlPattern` 和 `urlRegex` 不能同时传
-- `priority` 必须是整数
-- `headerMatchers` 必须是数组
-- 每个 header matcher 必须有 `name`
-- 每个 header matcher 必须至少有 `valueIncludes` 或 `valueRegex`
-- 目标页不存在、已关闭或无 websocket target 时直接报错
-
-### Matching Rules
-
-- 不支持空 header matcher
-- 不支持空正则
-- 不支持通过 richer matching 创建跨页规则
-- 同一请求只应用第一条命中的规则
-
-### Lifecycle Rules
-
-- 页面关闭时,绑定该 `pageId` 的规则与近期请求摘要继续按 Phase 6 规则清理
-- websocket 关闭时不保留悬挂 session
-- selected page 变化不影响已创建规则的 `pageId` 绑定
-
-## Testing Strategy
-
-Phase 7 继续沿用既有 TDD 路线,在 `tests/unit/hooks/ccs-browser-mcp-server.test.ts` 上扩展 deterministic harness 与行为断言。
-
-建议拆分为:
-
-1. **Schema / 参数失败测试**
- - `urlPattern` 与 `urlRegex` 同传时报错
- - `priority` 非整数时报错
- - `headerMatchers` 不是数组时报错
- - header matcher 缺 `name` 报错
- - header matcher 既无 `valueIncludes` 也无 `valueRegex` 报错
-
-2. **主路径测试**
- - `resourceType` 命中
- - `urlPattern` 命中
- - `urlRegex` 命中
- - `headerMatchers.valueIncludes` 命中
- - `headerMatchers.valueRegex` 命中
-
-3. **优先级与回归测试**
- - 更高 `priority` 的规则覆盖较低优先级规则
- - 同优先级仍按创建顺序命中
- - selected page 切换后规则仍绑定原 `pageId`
- - 页面关闭后 richer matching 规则与请求摘要一起清理
-
-4. **仓库验证顺序**
- - focused test
- - `bun run build:server`
- - `bun run format`
- - `bun run validate`
- - `bun run validate:ci-parity`
-
-## Documentation Impact
-
-如果 Phase 7 落地,`docs/browser-automation.md` 需要同步更新:
-
-- Phase 7 capability details
-- richer matching 示例
-- 当前仍未支持的范围:跨页规则、下载控制、请求体匹配等
-
-## Phase 7 Deliverable Boundary
-
-Phase 7 的交付结果应当是:
-
-- 用户可以继续用现有四个 interception 工具
-- 用户可以创建更精细的 page-bound 规则
-- 用户可以用 `priority` 控制命中顺序
-- 用户仍在同一 session-local interception 模型里工作
-- 代码不因为这期而引入新的全局作用域、下载控制或代理层复杂度
-
-这让 Browser MCP 的 network interception 从“最小可用”进入“更稳定可控”,但仍然保持单期可交付范围。
diff --git a/docs/reports/2026-04-19-browser-mcp-phase8-design.md b/docs/reports/2026-04-19-browser-mcp-phase8-design.md
deleted file mode 100644
index b2993bf6..00000000
--- a/docs/reports/2026-04-19-browser-mcp-phase8-design.md
+++ /dev/null
@@ -1,455 +0,0 @@
-# Browser MCP Phase 8 Design
-
-Last Updated: 2026-04-19
-
-## Goal
-
-在当前已完成并提交的 Browser MCP Phase 7 基线之上,为 CCS-managed `ccs-browser` MCP runtime 设计 Browser MCP Phase 8。
-
-本阶段延续历史 roadmap 中 Phase 7 预留的 file-transfer / lifecycle completion 方向,但按当前官方 CDP 能力边界做最小修正:
-
-- **下载控制**:采用 session-local、browser-scoped 的下载策略与下载结果摘要
-- **最小上传**:采用 page-scoped 的 file input 设置能力
-
-Phase 8 的目标是补齐“文件流转”这一类真实浏览器工作流缺口,让 browser MCP 不再只有页面交互与网络拦截,还能覆盖最常见的下载与表单文件上传场景。
-
-## Why Phase 8 Follows Phase 7
-
-历史 spec 的主路线是:
-
-- Phase 5:page/tab control
-- Phase 6:network interception + mock responses
-- Phase 7:file-transfer and lifecycle completion
-- Phase 8+:recording / replay / higher-level orchestration
-
-后来实际交付里,Phase 6 被拆成 6A / 6B,Phase 7 又继续完成了 richer request matching。因此当前 browser MCP 已经把 interception 线打磨到了一个较完整的最小闭环:
-
-- page-bound interception rules
-- session-local state
-- `continue` / `fail` / `fulfill`
-- richer request matching
-- recent request summaries
-
-下一阶段如果继续深挖 interception,会开始落入 request body matching、更复杂 boolean matcher groups、cross-page shared rules 这类更重的规则编排问题;而历史 roadmap 里原本预留的 file transfer 缺口仍未补上。
-
-因此,Phase 8 应该回到原 roadmap,优先补:
-
-- **download handling**
-- **minimal upload handling**
-
-这样既尊重了最初路线,也能让 browser MCP 覆盖更多真实 end-to-end workflow。
-
-## Scope Summary
-
-### In Scope
-
-1. **下载控制**
- - 为当前 attach session 设置下载策略:接受或拒绝下载
- - 支持 session-local 下载目录配置
- - 记录近期下载摘要
- - 支持取消进行中的下载
- - 继续兼容现有 `browser_wait_for_event(kind=download)` 事件等待能力
-
-2. **最小上传**
- - 为 `` 设置一个或多个本地文件
- - 支持当前已有 selector 作用域能力:`nth`、`frameSelector`、`pierceShadow`
- - 保持 selected page 解析语义
-
-3. **状态可见性**
- - 通过新的下载列表工具查看近期下载摘要与状态
- - 返回清晰的 upload / download 结果摘要
-
-### Explicitly Out of Scope
-
-- 原生系统文件选择器接管
-- drag-and-drop 上传
-- 下载文件内容读取、解析或回传
-- 上传后自动点击 submit 或自动编排后续页面流程
-- 跨 runtime 持久化下载策略或下载记录
-- 基于 interception 的下载内容改写
-- 录制 / 回放 / 宏编排
-- request body matching
-- 更复杂 boolean matcher groups
-- 跨页共享 interception rules
-
-## CDP Constraint and Scope Correction
-
-Phase 8 的关键设计修正来自当前官方 CDP 能力边界:
-
-### Uploads
-
-上传侧可基于 `DOM.setFileInputFiles` 实现,因此天然适合继续沿用当前 browser MCP 的 page-scoped / selector-scoped 工具模型。
-
-### Downloads
-
-下载侧主要依赖 Browser domain:
-
-- `Browser.setDownloadBehavior`
-- `Browser.cancelDownload`
-- `Browser.downloadWillBegin`
-- `Browser.downloadProgress`
-
-这些接口更接近 **browser-scoped / browser-context-scoped** 能力,而不是某个 page target 独占的 page-bound 能力。因此 Phase 8 不应伪装成“每页独立下载开关”,而应明确采用:
-
-- **下载控制:session-local, browser-scoped**
-- **上传控制:page-scoped**
-
-这是一个有意的混合作用域设计,但它与 CDP 现实能力一致,也避免了 misleading 的 page-local 承诺。
-
-## Architecture
-
-Phase 8 继续沿用 `lib/mcp/ccs-browser-server.cjs` 的单 runtime 架构,不引入新的 browser runtime,也不重写 Phase 5 selected page 模型或 Phase 6-7 的 interception 架构。
-
-本阶段分成两条并行但边界清晰的能力线:
-
-1. **Download control line**
- - browser-scoped CDP Browser domain 控制
- - session-local 下载策略与下载摘要
-2. **File input upload line**
- - page-scoped selector 解析
- - DOM file input 赋值
-
-### Design Principles
-
-- 下载控制尊重 CDP Browser domain 的真实作用域,不伪造成 page-bound
-- 上传继续复用已有 selector / frame / shadow 解析模型,不新建第二套选择器系统
-- 继续保持 session-local state,不持久化到磁盘
-- 继续保持最小增量策略,不把 download/upload 扩展成完整文件管理系统
-- 不为了 Phase 8 重构现有 wait / event / interception 基础设施
-
-## Tool Surface
-
-Phase 8 推荐新增三个工具。
-
-### 1. `browser_set_download_behavior`
-
-为当前 attach session 设置下载策略。
-
-建议参数:
-
-- `behavior: "accept" | "deny"`
-- `downloadPath?: string`
-- `eventsEnabled?: boolean`
-
-行为:
-
-- `behavior=accept` 时允许下载
-- `behavior=deny` 时拒绝下载
-- `downloadPath` 仅在 accept 时有效;如省略,则 runtime 选择 session-local 默认下载目录
-- `eventsEnabled` 默认开启,保证下载事件和结果摘要可见
-- 作用域为当前 attach session / browser context,而不是单个页面
-
-返回字段建议最小包含:
-
-- `scope: browser`
-- `behavior`
-- `downloadPath`
-- `eventsEnabled`
-- `status`
-
-### 2. `browser_list_downloads`
-
-列出当前 MCP runtime 记录的近期下载摘要。
-
-建议参数:
-
-- `limit?: number`
-- `pageId?: string`
-
-行为:
-
-- 默认返回最近下载摘要
-- 可按触发下载时记录的 `pageId` 过滤
-- 不读取下载文件内容
-- 只返回摘要和状态
-
-返回字段建议最小包含:
-
-- `downloadId`
-- `guid`
-- `pageId`
-- `url`
-- `suggestedFilename`
-- `status`
-- `savedPath`
-- `startedAt`
-- `finishedAt`
-
-### 3. `browser_cancel_download`
-
-取消进行中的下载。
-
-建议参数:
-
-- `downloadId?: string`
-- `guid?: string`
-
-行为:
-
-- 按 runtime 记录的 `downloadId` 或底层 `guid` 定位目标
-- 调用 Browser domain cancel 能力
-- 更新 `recentDownloads` 中对应项状态
-
-约束:
-
-- `downloadId` 与 `guid` 至少提供一个
-- 两者同时提供时必须指向同一条下载记录,否则报错
-
-### 4. `browser_set_file_input`
-
-为 `` 直接设置本地文件。
-
-建议参数:
-
-- `selector: string`
-- `files: string[]`
-- `pageIndex?: number`
-- `pageId?: string`
-- `nth?: number`
-- `frameSelector?: string`
-- `pierceShadow?: boolean`
-
-行为:
-
-- 解析目标页
-- 解析 selector 作用域
-- 定位目标节点
-- 要求目标是 ``
-- 将本地文件路径集合设置到该 input
-- 返回设置结果摘要
-
-返回字段建议最小包含:
-
-- `pageId`
-- `pageIndex`
-- `selector`
-- `fileCount`
-- `status`
-
-## State Model
-
-Phase 8 继续使用 session-local in-memory state。
-
-### `downloadBehaviorState`
-
-存储当前 attach session 的下载行为配置。
-
-建议字段:
-
-- `behavior`
-- `downloadPath`
-- `eventsEnabled`
-- `updatedAt`
-
-关键约束:
-
-- browser-scoped
-- 不绑定 pageId
-- runtime 重启后丢失
-
-### `recentDownloads`
-
-记录近期下载摘要。
-
-建议字段:
-
-- `downloadId`
-- `guid`
-- `pageId`
-- `url`
-- `suggestedFilename`
-- `status: "started" | "inProgress" | "completed" | "canceled" | "denied" | "failed"`
-- `savedPath`
-- `receivedBytes`
-- `totalBytes`
-- `startedAt`
-- `finishedAt`
-
-关键约束:
-
-- 固定上限,建议 100 条
-- 只保留摘要,不读文件内容
-- 通过 `guid` 关联 Browser domain 下载事件
-
-### Existing selected page state
-
-上传工具继续复用现有 selected page 模型:
-
-- 显式 `pageIndex` 优先
-- 否则走 selected page
-- stale selected page 时回退到第一可用页面
-
-## Data Flow
-
-### Download behavior update flow
-
-1. `browser_set_download_behavior` 校验参数
-2. 若 `behavior=accept` 且未提供 `downloadPath`,计算 session-local 默认下载目录
-3. 调用 `Browser.setDownloadBehavior`
-4. 更新 `downloadBehaviorState`
-5. 返回当前配置摘要
-
-### Download observation flow
-
-1. runtime 接收 `Browser.downloadWillBegin`
-2. 生成 `downloadId`
-3. 写入 `recentDownloads`,状态为 `started`
-4. 记录触发时关联的 `pageId`(若能确定)
-5. 若后续收到 `Browser.downloadProgress`:
- - 更新 `receivedBytes` / `totalBytes`
- - 当 state=`completed` 时写入 `finishedAt` 和可用 `savedPath`
- - 当 state=`canceled` 时更新状态
-
-### Download cancel flow
-
-1. `browser_cancel_download` 解析目标记录
-2. 调用 `Browser.cancelDownload`
-3. 更新 `recentDownloads` 为 `canceled`
-4. 返回取消结果摘要
-
-### File input upload flow
-
-1. `browser_set_file_input` 解析目标页
-2. 解析 `selector` / `nth` / `frameSelector` / `pierceShadow`
-3. 定位 DOM 节点
-4. 校验目标是 ``
-5. 校验所有本地文件路径存在且为普通文件
-6. 调用 `DOM.setFileInputFiles`
-7. 返回设置结果摘要
-
-## Error Handling and Boundary Rules
-
-### `browser_set_download_behavior`
-
-- `behavior` 只能是 `accept` 或 `deny`
-- `behavior=deny` 时不接受 `downloadPath`
-- `downloadPath` 不可写时报错
-- Browser domain 下载能力不可用时报错
-
-### `browser_list_downloads`
-
-- `limit` 越界时回退到安全默认值
-- `pageId` 不存在时返回空列表,不报错
-
-### `browser_cancel_download`
-
-- `downloadId` 与 `guid` 至少传一个
-- 指定下载不存在时报错
-- 下载已完成时取消应报明确错误或返回 no-op 状态,但语义必须固定
-
-### `browser_set_file_input`
-
-- `pageIndex` 与 `pageId` 不能同时传
-- `selector` 不能为空
-- `files` 必须是非空数组
-- 文件不存在时报错
-- 文件路径不是普通文件时报错
-- selector 无匹配时报错
-- 多匹配但未提供 `nth` 时应保持与当前 selector 工具一致的目标解析语义
-- 命中的元素不是 `` 时报错
-- 跨域 iframe 不支持
-- closed shadow root 不支持
-
-## Interaction with Existing Capabilities
-
-### With `browser_wait_for_event`
-
-Phase 8 不替换 `browser_wait_for_event(kind=download)`;它继续负责:
-
-- 等待下载开始事件
-- 作为轻量事件观察能力存在
-
-Phase 8 新增的下载工具负责:
-
-- 设置下载策略
-- 查看下载摘要
-- 取消下载
-
-### With selected page semantics
-
-- 下载行为是 browser-scoped,不依赖 selected page
-- 上传行为继续遵循 selected page 解析语义
-- 这两者的作用域不同是有意设计,不属于不一致 bug
-
-### With interception state
-
-- 下载工具不复用 interception rule 管理面
-- 下载记录与 request summaries 是并行状态,不相互嵌套
-- 不把 download handling 强行建模成 interception action
-
-## Testing Strategy
-
-Phase 8 继续扩展:
-
-- `tests/unit/hooks/ccs-browser-mcp-server.test.ts`
-
-并在 deterministic harness 上增加最小 download / upload 模拟能力。
-
-### Required download coverage
-
-1. 工具列表与 schema 暴露正确
-2. `browser_set_download_behavior` accept 成功
-3. `browser_set_download_behavior` deny 成功
-4. `behavior=deny` + `downloadPath` 报错
-5. 下载开始后 `browser_list_downloads` 能看到 started 摘要
-6. 下载完成后能看到 completed 状态与文件路径
-7. 下载取消后能看到 canceled 状态
-8. `browser_wait_for_event(kind=download)` 继续兼容
-9. `limit` 和 `pageId` 过滤生效
-
-### Required upload coverage
-
-1. 单文件上传成功
-2. 多文件上传成功
-3. selector 无匹配失败
-4. 命中的不是 file input 失败
-5. 文件不存在失败
-6. `frameSelector` 作用域成功
-7. `pierceShadow` 作用域成功
-8. 省略 `pageIndex/pageId` 时命中当前 selected page
-9. 显式 `pageIndex` 仍覆盖 selected page
-
-### Repository validation order
-
-继续遵循该区域已稳定使用的验证顺序:
-
-1. focused browser MCP unit tests
-2. `bun run build:server`
-3. `bun run format`
-4. `bun run validate`
-5. `bun run validate:ci-parity`
-
-## Documentation Impact
-
-如果 Phase 8 实现落地,至少需要同步:
-
-- `docs/browser-automation.md`
-
-需要新增:
-
-- Phase 8 capability details
-- 下载控制与上传示例
-- browser-scoped downloads / page-scoped uploads 的作用域说明
-- 新的 out-of-scope 边界说明
-
-## Worktree Requirement
-
-后续实现不应继续直接在当前 Phase 7 worktree 上混写。
-
-推荐隔离方式:
-
-1. 保留 `feat/browser-mcp-hover-phase7` 作为已完成 checkpoint
-2. 基于其已验证提交创建新的 Phase 8 worktree
-3. 在新 worktree 中完成 Phase 8 plan 与实现
-
-## Success Criteria
-
-Phase 8 成功的标志是:
-
-1. 用户可以显式控制当前 attach session 的下载接受/拒绝行为
-2. 用户可以查看近期下载摘要并取消进行中的下载
-3. 用户可以向 `` 设置本地文件
-4. 下载与上传能力都遵循清晰、真实的作用域语义
-5. 本期不引入 drag-and-drop、原生文件选择器接管、内容读取或 orchestration 复杂度
-
-这使 Browser MCP 在当前阶段从“页面交互 + 网络拦截”扩展到“最小文件流转闭环”,为后续更高阶的录制、回放和 workflow orchestration 打下更完整的基础。