Files
cc-web/.planning/2026-08-11-unify-ccweb-message-reply/findings.md

92 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 发现与决策:统一 ccweb 消息回传接口
## 需求
- 将 `ccweb_send_message` 与 `ccweb_request_reply` 合并为一个公开工具。
- 使用显式参数选择单向投递或自动回传。
- 优化工具描述、目标对话提示和来源续跑提示。
- 保留旧调用的兼容能力,但不让新模型继续在两个公开工具间选错。
- 本次需要实际落地并通过回归。
## 已确认事实
- `requestCrossConversationReply()` 当前只是
`sendCrossConversationMessage(..., { expectReply: true })` 的薄包装。
- 正式 MCP 定义位于 `lib/ccweb-mcp-server.js`,Codex App 备用定义位于
`server.js`,两处描述已出现漂移。
- `ccweb_create_conversation` 已经使用 `requestReply` 参数,现有公开 API 风格不一致。
- `buildCrossConversationRuntimeText()` 当前只标注来源标题和 ID,不携带是否自动回传。
- `buildCrossConversationReplyAutoRunText()` 当前只包含目标标题和返回正文,缺少
`requestId`、原始请求和完整性检查指令。
- 真实会话中曾对明确要求“完成后汇报/最终验收”的任务误用
`ccweb_send_message`;同一会话此前使用过 `ccweb_request_reply`,说明问题不是工具
不可发现,而是选择语义不够强。
- 真实会话还出现过目标返回“完成定位、准备修改”后仍继续工作的情况;提示词可降低
概率,但“turn 完成是否等于任务完成”仍是协议级风险。
## 并发与工作树基线
- 当前另有两个非本对话的 `running` 对话:任务看板、失败插入卡片。
- `server.js`、`lib/ccweb-mcp-server.js`、`scripts/regression.js` 已有未提交改动,均与本任务重叠。
- `.planning/.active_plan` 指向 `2026-08-11-help`,`.trellis/.current-task` 指向
`.trellis/tasks/08-11-task-board`;不得覆盖。
- 本任务使用 `.planning/2026-08-11-unify-ccweb-message-reply/` 保存独立上下文。
- 已创建 Trellis 任务 `.trellis/tasks/08-11-unify-ccweb-message-reply/`,但不会执行
`task.py start`:全局 `.trellis/.current-task` 正被另一个运行中对话使用。后续实施与
审查子代理必须显式读取本任务路径,不能依赖全局 current-task。
## 技术决策
| 决策 | 理由 |
|---|---|
| `replyMode` 必填、无默认值 | 避免模型省略参数后静默失去回传 |
| 值为 `one_way`、`return_and_continue` | 名称直接表达真实副作用,不暗示同步等待 |
| 公开列表移除旧工具,内部 dispatcher 保留别名 | 兼顾新调用清晰度与存量线程兼容 |
| 共享工具定义为单一来源 | 防止 MCP 与备用 dynamic tools 文案/Schema 漂移 |
| 回传模式目标提示禁止手工回复 | 防止同一结果重复投递或形成环路 |
| 来源续跑先判断完整性 | 防止把“已返回”误判成“已完成” |
| 直接复用 `CCWEB_MCP_TOOLS` 生成 Codex App 备用定义 | `server.js` 已导入正式工具清单,无需新增第三个契约模块 |
## 最新代码基线
- `server.js` 顶部已导入 `{ TOOLS: CCWEB_MCP_TOOLS }`,但
`codexAppCommunicationDynamicTools()` 仍手写重复定义。
- 最小单一来源方案:正式定义继续留在 `lib/ccweb-mcp-server.js`;该模块同时导出
reply mode 常量;`server.js` 从 `CCWEB_MCP_TOOLS` 按通信工具白名单筛选并添加
`namespace: 'ccweb'`。
- 此方案同时统一所有既有通信工具描述,且不会把 task-board 工具意外加入备用列表。
- 公开 TOOLS 不能兼作唯一调用 allowlist;需要单独的 hidden legacy name 集合,避免
已缓存 `ccweb_request_reply` 的旧线程在到达 dispatcher 前失败。
- `scripts/regression.js` 现有 `assertCcwebListConversationsScopeContract()` 会从
`server.js` 的手写 dynamic tool 源码中截取 `ccweb_list_conversations` schema;改成
单一来源后该断言也必须改为调用 `codexAppCommunicationTools()` 并比较正式定义,
否则正确的去重实现会被旧静态断言误报。
- 当前任务看板对话不是陈旧运行标记:其 `codexapp-state.json` 持续更新,正在做隔离
浏览器验收并已发现新增列 `description` 契约缺陷。它后续可能修改 `server.js` 与
`scripts/regression.js`,本任务必须继续等待其生产改动闭环。
## 待验证
- 现有测试是否直接断言公开工具数量或旧工具名称。
- Codex App 备用 dynamic tool 路径是否仍有实际回归覆盖。
- 旧线程调用已不在工具列表中的旧名称时,内部 MCP dispatcher 是否仍可接收。
- 原始请求内容加入 pending 状态是否涉及持久化格式兼容。
- 正式 MCP 的 `tools/call` 是否在公开 TOOLS 之外保留隐藏旧名(必须保留)。
## Trellis 规范结论
- 仓库只声明 backend/frontend 两层;本任务属于 backend + 跨层协议,不需要加载前端组件规范。
- backend error handling 基本为空,现有 `mcpToolError` 行为应作为事实规范保留。
- backend quality 的已填内容仅针对部分 JSON 预览,与本任务无直接约束。
- `cross-layer-thinking-guide.md` 要求显式定义工具 Schema → dispatcher → pending 状态 →
目标运行提示 → 来源续跑提示的完整数据流,并在入口集中校验。
- `code-reuse-thinking-guide.md` 明确要求相同常量/定义单一来源;支持让 Codex App
备用工具列表直接派生自正式 MCP 定义。
## 资源
- `server.js`:跨对话发送、回传、运行提示、dynamic tool 定义。
- `lib/ccweb-mcp-server.js`:正式 MCP 工具清单与输入 Schema。
- `scripts/regression.js`:跨对话 MCP 端到端回归。
- `README.md`:公开工具说明。