Revise the fast-slow r2 proposal after review

Why: stages 1-4 needed spec conflicts closed before another review, without treating the agent review as approval.
Evidence: SELF consistency check over NB01-NB24; product tests NOT_RUN.
Impact: proposal text only. Review status stays unreviewed. No business code.
Refs: docs/proposals/2026-10-15-fast-slow-r2-nonblocking.md
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-15 05:56:20 +00:00
co-authored by Cursor
parent 0f06abd57c
commit a672adb7aa
3 changed files with 237 additions and 181 deletions
@@ -1,21 +1,22 @@
---
title: 快慢通道 r2 非阻塞对话与任务卡实施计划
date: 2026-10-15
revision: r2-draft
revision: r2-draft.2
status: pending-review
owner: weichen
execution: plan-only
parent: 2026-10-15-fast-slow-r2-nonblocking.md@r2-draft
parent: 2026-10-15-fast-slow-r2-nonblocking.md@r2-draft.2
---
# 快慢通道 r2 实施计划
状态:**阶段 5 文稿已起草,待人工评审。** 批准前不写业务代码,不推送,不合入。
规格依据 [r2 增补方案](2026-10-15-fast-slow-r2-nonblocking.md)。r1.1 在 r2 阶段 4 批准前仍然有效。
状态:**阶段 5 文稿已按阶段 1–4 的修订联动更新,仍未评审。** 须等阶段 1–4 通过后再单独评审。
批准前不写业务代码,不推送,不合入。
规格依据 [r2 增补方案](2026-10-15-fast-slow-r2-nonblocking.md) @ r2-draft.2。r1.1 在 r2 阶段 4 批准前仍然有效。
**Goal:** 先让已有完整结果、进展、滚动和选择状态按任务归位,再把用途选择和完成通知改成非阻塞。
**Goal:** 先闭合非阻塞闭环:完整结果、原卡到达、卡内选择、已读、请求复用,以及右栏不可见时的完整操作。再做进展归并、滚动、时间和面板整理。
**Architecture:** 服务端任务卡仍是唯一快照。增量 1 只改投影、回放归并和滚动。增量 2 才改完成通知、选择状态、任务请求幂等和排队持久化。
**Architecture:** 服务端任务卡仍是唯一快照。增量 1 交付全部 P0,并保持 NB14、NB23。增量 2 交付 P1。不把前台 outbox 做成跨刷新存储。
**Tech Stack:** Go(Core/Backend)、React+TypeScript(UI/Frontend)、既有 ActivityCard、HITL、事件 seq 与 `make evidence`。
@@ -23,23 +24,26 @@ parent: 2026-10-15-fast-slow-r2-nonblocking.md@r2-draft
- 视觉继续消费 `@ui/tokens.css`、`mk-*` 和 Collapsible。不新增裸色值、私有 `@keyframes`、行内字号或 `<details>`。
- 异步状态只有一个所有者。事件按 seq 处理,过期事件丢弃。
- 折叠和归并是展示规则。原始过程、思考、工具和输出继续保存。
- 折叠和归并是展示规则。已保存且有权查看的公开过程、工具名、授权参数和输出继续可回放。隐藏思维链、系统或开发者提示、凭据、原始请求载荷和未授权工具数据不进入投影。
- 右栏关闭、切到文件或窄屏时,中栏展示同一 taskId 的完整卡片与操作。
- 跨仓顺序:Core 契约 → Backend → UI → Frontend → Documents 指针与 Dev gitlink。组合验证用 `make test`。
- 与 `feature/fast-slow-u2-u3-plan` 并行。本分支从 Dev `origin/main` 的 R0 `63e70d8b91ccb1691ce9b78a373e4e8bc9da24a2` 切出,不从该 U3 分支堆叠。
- 与 `feature/fast-slow-u2-u3-plan` 并行。本分支从 Dev `origin/main` 的 R0 `63e70d8b91ccb1691ce9b78a373e4e8bc9da24a2` 切出;修订前已同步到 `692735e91d6a9ab07ddd3686feb60a56b270728a`。不从该 U3 分支堆叠。
- 证据写入任务卡只用 `CMD=… make evidence`。本地记录标 SELF。合入所需的 GATE 不在本计划的交付终点里。
## 明确不做
- 不跑新的模型质量试验,不改模型路由。
- 不在增量 1 移除 `startNoticeRun`。自动汇报的取消属于增量 2,避免半套行为。
- 不把「先不选择」或自由输入解释为授权同意。
- 不离线重写旧会话的模型正文。存量只改读取和展示。
- 不实现前台消息的跨刷新、跨会话恢复,不新增 outbox 的服务端草稿、恢复鉴权或删除语义。
- 不把工具开始或结束记成新的阶段记录。
## 增量 1:接通完整结果,归并进展,解开滚动
## 增量 1:P0 非阻塞闭环
对应 NB01–NB06、NB10 的历史文案、NB15、NB17 的消息与卡片时间、NB20。
对应 NB01、NB02、NB05、NB07、NB08、NB09、NB10、NB11、NB12、NB13、NB18、NB19、NB21、NB22、NB24。
NB14 与 NB23 在本增量保持,不单独排工作项。
完成条件:回放测试里重复累计进展只占一行;完成卡能打开已保存全文;中栏滚动不带动右栏;已处理选择显示实际答案。增量 1 结束时,整理完成仍可能启动现有通知回合。这一点在任务卡写明,避免把增量 1 说成完整场景已通过。
完成条件:方案 §1.2 的六步走查里,完成不新增中栏消息,选择不锁住无关对话,重复明确指令不新开任务,右栏关闭时中栏能读摘要、处理选择并打开文件。同一摘要请求只执行一次。增量 1 结束时,重复进展行和滚动联动仍可能存在,留在增量 2。
### W1 — Backend:完成卡读取最终结果
@@ -48,58 +52,9 @@ parent: 2026-10-15-fast-slow-r2-nonblocking.md@r2-draft
- Modify: `modules/backend/internal/runmgr/runmgr.go`(约 2241 行的 160 字摘要)
- Test: `modules/backend/internal/runmgr` 下现有完成卡测试
**内容:** 用户可见概览使用已形成的要点。没有可靠要点时写入「整理结果已生成,查看完整结果」,并保留全文入口。停止把 `truncate(fullText, 160)` 当作摘要。旧卡已写入的短摘要按方案 §4.9 只读展示。
**内容:** 用户可见概览使用已形成的要点。没有可靠要点时写入「整理结果已生成,查看完整结果」,并保留全文入口。停止把 `truncate(fullText, 160)` 当作摘要。旧卡已写入的短摘要按方案 §4.9 只读展示,展示文案的存量折叠留到增量 2 的 NB20。
### W2 — Backend/Frontend:进展按任务归并
**Files:**
- Modify: `modules/backend/internal/runtime/sub_loop.go`(约 210 行,累计文本进度)
- Modify: `modules/frontend/src/live.ts`(约 244 行,`runEventsToTimeline`)
- Modify: `modules/frontend/src/store.ts`(`agent.progress` 写入)
- Test: `modules/frontend/test/live.test.ts`
**内容:** 同一子任务的文本流更新同一条展示。阶段变化和工具起止另记。原始事件保留。前台折叠记录只保留指向该任务的入口,子任务日志进入该任务的执行记录。
### W3 — Frontend:两栏独立滚动
**Files:**
- Modify: `modules/frontend/src/components/Conversation.tsx`(约 659 行)
- Modify: `modules/frontend/src/scrollsync.ts`
- Test: `modules/frontend/test/scrollsync.test.ts`
**内容:** 去掉滚动百分比联动。保留点击「查看关联任务」和「定位发起消息」后的定位与 `flashElement`。
### W4 — Backend/UI:选择结果替换「可自由输入」
**Files:**
- Modify: `modules/backend/internal/runmgr/runmgr.go`(约 804 行)
- Modify: UI 的确认卡投影消费处(`ActivityCardView` / `InlineConfirmCard`)
- Test: 投影测试覆盖未处理和已处理
**内容:** 未处理时卡片内有真实补充输入。已处理后展示「已选择:…」以及补充要求,去掉失效提示。增量 1 仍可沿用现有等待语义;非阻塞由增量 2 完成。
### W5 — 时间标签
**Files:** Frontend 消息与任务卡组件;必要时 Core 卡片时间字段。
**内容:** 消息时刻来自创建时间,后台更新不回写。卡片显示创建、更新、完成。跨天显示日期,悬停显示完整时间。
### 增量 1 测试与停止
测试:Backend 完成卡单测、Frontend 进展回放与滚动单测、UI 守护测试。浏览器走查留到阶段 7。
停止条件:归并导致原始事件不可回放;完成卡在全文存在时仍只显示开头;滚动改动把定位高亮一起删掉。出现任一条即停增量 1,不进入增量 2。
## 增量 2:非阻塞选择与到达通知
对应 NB07–NB14、NB16、NB18、NB19,以及 NB10、NB17 的剩余部分。前置:增量 1 已提交,且 r2 阶段 4、5 已批准。
完成条件:方案 §1.2 的六步走查和 §5 的边界都能在测试或浏览器里指出对应证据。同一摘要请求只执行一次。结果到达不增加中栏消息。
### W6 — Backend:完成只更新原卡
### W2 — Backend:完成和失败只更新原卡
**Files:**
@@ -107,23 +62,24 @@ parent: 2026-10-15-fast-slow-r2-nonblocking.md@r2-draft
- Modify: `modules/backend/internal/runtime/verify.go`(约 43 行 `materialNoticeBackstopReason`)
- Test: 通知与终轮兜底的现有测试
**内容:** 材料整理完成时更新原卡、写未读、发一次轻提示事件。移除强制汇报和强制 `confirm_choice`。不调用 `claimConversation` 来占住会话。失败同样更新原卡,不启动汇报回合。
**内容:** 材料整理完成或失败时更新原卡、写未读、发一次轻提示事件。移除强制汇报和强制 `confirm_choice`。不调用 `claimConversation` 来占住会话。失败保留已保存的部分结果和原因,不显示成功完成。
真实模型前后对照:此工作项改变提示词和终轮门禁。状态 `NOT_RUN`。原因:2026-10-15 用户确认模型质量试验不是这些交互修复的前置条件。补救:增量 2 获实施授权后,按 `modules/backend/eval/live/` 或等价最小重放集补一次任务级对照,写入任务卡并标来源。未补之前,任务卡不得把该行为写成「已用真实模型验证」。
真实模型前后对照:此工作项改变提示词和终轮门禁。状态 `NOT_RUN`。原因:2026-10-15 用户确认模型质量试验不是这些交互修复的前置条件。补救:增量 1 获实施授权后,按 `modules/backend/eval/live/` 或等价最小重放集补一次任务级对照,写入任务卡并标来源。未补之前,任务卡不得把该行为写成「已用真实模型验证」。
### W7 — Core/Backend:选择状态与任务请求
### W3 — Core/Backend:选择、已读与任务请求
**Files:**
- Modify: Core HITL / ActivityCard 契约(选择状态、请求键、未读)
- Modify: Core HITL / ActivityCard 契约(选择状态、请求键、未读、结果版本)
- Modify: `modules/backend/internal/runmgr/material.go` `materialKey`(约 44 行)及派发去重
- Test: 幂等、过期选择、授权隔离
- Modify: `modules/backend/internal/runmgr/runmgr.go`(约 805 行,自由输入投影)
- Test: 幂等、过期选择、已读转换、授权隔离、安全投影夹具
**内容:** 选择状态为待选、已选、暂不处理。请求键为材料内容 hash、解析版本、用途、请求版本。按钮和绑定后的聊天消息共用该键。重复提交返回已有任务。重新生成或改变范围才递增版本。内容身份不再只靠文件名和字数。
**内容:** 选择状态为待选、已选、暂不处理。暂不处理可回到待选且不新建请求。已读只在展开详情、完整结果或显式标记时发生;新结果版本重新未读。请求键为材料内容 hash、解析版本、用途、请求版本。按钮和绑定后的聊天消息共用该键。重复提交和重复的明确指令返回已有任务。重新生成或改变范围才递增版本。过期或已处理的选项刷新为服务端状态,不能再提交。自由输入和「先不选择」不算授权同意。投影排除 NB23 列出的隐藏内容。
确定性绑定先覆盖:卡片输入、显式任务引用、同时点明该材料与用途动作的句子。其余消息保持为新话题,并保留原选择。含糊消息只澄清。
### W8 — Frontend/UI:卡内选择、未读、引用、抽屉
### W4 — Frontend/UI:同一张卡的两种落位
**Files:**
@@ -132,34 +88,78 @@ parent: 2026-10-15-fast-slow-r2-nonblocking.md@r2-draft
- Modify: UI 任务卡与确认卡
- Test: 组件测试与 `design-guard`
**内容:** 单选、多选、补充输入、「按此处理」、「先不选择」。工作入口未读数。输入区可移除的引用标签。收起提示「后台工作 N 项 · 新结果 M 项」。窄屏使用同一面板的抽屉。右栏两区按方案 §4.8 排序,阅读中不自动跳转。
**内容:** 右栏「工作」可见时,中栏只留关联入口。右栏关闭、切到文件或窄屏时,中栏展开同一 taskId 的完整卡片:摘要、依据、单选或多选、补充输入、「按此处理」、「先不选择」、打开文件。处理后展示实际选择。输入区放可移除的引用标签。未引用时不把结果版本写成已经读过。收起提示「后台工作 N 项 · 新结果 M 项」和窄屏抽屉打开同一面板。
### W9 — 排队持久化
### W5 — 聊天队列不被后台占用
**Files:**
- Modify: `modules/frontend/src/outbox.ts` 及发送路径
- Modify: Backend 会话占用,使后台 run 和普通待选不再返回让聊天一直排队的占用
- Test: 刷新后排队仍在;后台整理进行中的新消息能进入对话
- Test: 后台整理进行中的新消息能进入对话
**内容:** 前台生成中的短暂排队写入可恢复存储。切换会话和刷新后仍可发送。危险授权继续只阻塞依赖它的工作。
**内容:** 不修改 `modules/frontend/src/outbox.ts` 的存储,也不把排队消息写成可跨刷新恢复的记录。前台生成中的短暂内存排队可以保留。危险授权继续只阻塞依赖它的工作。
### 增量 1 测试与停止
测试:完成卡、通知、请求幂等、选择与已读状态机、右栏关闭时的同一任务、授权隔离、NB23 夹具。浏览器走查留到阶段 7。
停止条件:无关消息被静默当成选择答复;「先不选择」或自由输入触发了需授权的动作;同一请求键产生两份结果;完成或失败通知再次插入中栏长回复;右栏关闭时不能读摘要或提交选择;展开内容出现 NB23 排除项。出现任一条即停增量 1,不进入增量 2。
## 增量 2:P1 归并、滚动、时间与面板
对应 NB03、NB04、NB06、NB15、NB16、NB17、NB20。前置:增量 1 已提交,且 r2 阶段 4、5 已批准。
完成条件:重复累计进展只占一行;工具起止不新增阶段记录;中栏滚动不带动右栏;完整时间戳有悬停、键盘、触屏和读屏路径;旧的 160 字摘要被标明为当时保存的开头。
### W6 — Backend/Frontend:进展按任务归并
**Files:**
- Modify: `modules/backend/internal/runtime/sub_loop.go`(约 210 行,累计文本进度)
- Modify: `modules/frontend/src/live.ts`(约 244 行,`runEventsToTimeline`)
- Modify: `modules/frontend/src/store.ts`(`agent.progress` 写入)
- Test: `modules/frontend/test/live.test.ts`
**内容:** 同一子任务的文本流更新同一条展示。阶段变化才新增阶段记录。工具开始和结束只更新活动行并进入执行记录。原始事件保留。运行中的要点不收「我来检索」和工具调用。旧会话按同一规则折叠,详细记录仍按 seq 可查。
### W7 — Frontend:两栏独立滚动与历史分区
**Files:**
- Modify: `modules/frontend/src/components/Conversation.tsx`(约 659 行)
- Modify: `modules/frontend/src/scrollsync.ts`
- Modify: 右栏当前工作 / 工作历史
- Test: `modules/frontend/test/scrollsync.test.ts`
**内容:** 去掉滚动百分比联动。保留点击「查看关联任务」和「定位发起消息」后的定位与 `flashElement`。当前工作与工作历史按方案 §4.8 排序。阅读中的卡不因更新而自动排序、展开或跳转,只显示「有 1 项更新」。
### W8 — 时间标签
**Files:** Frontend 消息与任务卡组件;必要时 Core 卡片时间字段。只用 `@ui` 已有原语。
**内容:** 消息时刻来自创建时间,后台更新不回写。卡片显示创建、更新、完成。跨天显示日期。完整时间戳同时支持悬停、键盘聚焦、触屏点按和屏幕阅读器(`time` 的 `datetime` 与完整本地时间的可访问名称)。选择记录带提交时间。
### 增量 2 测试与停止
测试:请求幂等、选择状态机、未读与轻提示、刷新恢复、授权隔离。阶段 7 用方案 §1.2 和边界做浏览器走查,含窄屏。
测试:进展回放、滚动、时间的非悬停路径、旧会话折叠。阶段 7 用方案 §1.2 和边界做浏览器走查,含窄屏。
停止条件:无关消息被静默当成选择答复;「先不选择」或自由输入触发了需授权的动作;同一请求键产生两份结果;完成通知再次插入中栏长回复;刷新丢排队。出现任一条即停止增量 2 的后续工作项。
停止条件:归并导致原始事件不可回放;工具起止被写成新的阶段记录;完成卡在全文存在时仍只显示开头;滚动改动把定位高亮一起删掉;完整时间只剩悬停。出现任一条即停止增量 2 的后续工作项。
## 验收映射
| 场景 | 需求 | 增量 | 证据形态 |
|---|---|---|---|
| 上传后一张材料卡持续更新 | NB02 NB03 | 1 | Backend/Frontend 测试 |
| 重复进展不刷行,全文可读 | NB04 NB05 NB20 | 1 | `live.test.ts` 与完成卡测试 |
| 滚动独立,点击才定位 | NB15 | 1 | `scrollsync.test.ts` |
| 整理完成不新增中栏回合 | NB07 | 2 | 通知测试;浏览器走查留阶段 7 |
| 「总结一下这份材料」只启动一次摘要 | NB12 NB13 | 2 | 请求键测试 |
| 先不选择、右栏关闭、刷新、重复点击、过期选择、失败 | NB09–NB11 NB14 NB16 NB18 NB19 | 2 | 状态机测试;浏览器走查留阶段 7 |
| 上传后一张材料卡持续更新 | NB02 | 1 | Backend 任务身份测试 |
| 整理完成不新增中栏回合,失败同样留在原卡 | NB07 NB21 | 1 | 通知测试;浏览器走查留阶段 7 |
| 全文可读,没有要点时用诚实入口 | NB05 | 1 | 完成卡测试 |
| 「总结一下这份材料」第二次不新开摘要 | NB12 NB13 | 1 | 请求键测试 |
| 先不选择可重新展开;过期选择不能再提交;已读与再次更新 | NB09–NB11 NB22 NB24 | 1 | 状态机测试 |
| 右栏关闭仍能读、选、打开文件 | NB01 NB18 | 1 | 同一 taskId 测试;浏览器走查留阶段 7 |
| 后台进行中新消息进入对话 | NB19 | 1 | 会话占用测试 |
| 授权放弃不算同意;展开不见隐藏内容 | NB14 NB23 | 1 | 回归夹具 |
| 重复进展不刷行,工具起止不进阶段记录 | NB03 NB04 NB06 NB20 | 2 | `live.test.ts` |
| 滚动独立,点击才定位;历史分区不抢阅读 | NB15 NB16 | 2 | `scrollsync.test.ts` |
| 完整时间不只有悬停 | NB17 | 2 | 组件测试;读屏路径留阶段 7 |
阶段 7 之前,上表浏览器项保持 `NOT_RUN`。单测通过只证明机制。
@@ -167,17 +167,19 @@ parent: 2026-10-15-fast-slow-r2-nonblocking.md@r2-draft
| 仓库 | 增量 1 | 增量 2 |
|---|---|---|
| Core | 卡片时间字段,若现有字段不够 | 选择状态、请求键、未读 |
| Backend | `runmgr.go` 完成摘要;`sub_loop.go` 进度 | `deliverNotices`、`verify.go`、`material.go`、会话占用 |
| UI | 选择结果展示 | 卡内选择、未读、抽屉 |
| Frontend | `live.ts`、`store.ts`、`Conversation.tsx`、`scrollsync.ts` | `ConversationWork.tsx`、`outbox.ts`、引用标签 |
| Core | 选择状态、请求键、未读、结果版本 | 卡片时间字段,若现有字段不够 |
| Backend | `runmgr.go` 完成摘要、`deliverNotices`、`verify.go`、`material.go`、会话占用 | `sub_loop.go` 进度 |
| UI | 卡内选择、未读、右栏关闭时的完整卡 | 历史分区、时间 |
| Frontend | `Conversation.tsx`、`ConversationWork.tsx`、引用标签 | `live.ts`、`store.ts`、`scrollsync.ts` |
| Documents | 本计划与方案状态 | 获批后回写进展 |
| Dev | gitlink 与任务卡 | gitlink 与任务卡 |
`modules/frontend/src/outbox.ts` 不在本计划的修改范围内。
## 评审
| 阶段 | 对象 | 结论 |
|---|---|---|
| 5 实施计划 | 本稿增量 1、增量 2 | 未评审 |
| 5 实施计划 | 本稿增量 1、增量 2 @ r2-draft.2 | 未评审 |
批准本稿并且阶段 4 已通过之后,才允许按增量 1 写业务代码。增量 2 在增量 1 完成并确认偏差后继续;若增量 1 改变了本计划的接口或顺序,先修订本稿再继续。
阶段 1–4 通过并且本稿获批之后,才允许按增量 1 写业务代码。增量 2 在增量 1 完成并确认偏差后继续;若增量 1 改变了本计划的接口或顺序,先修订本稿再继续。
@@ -1,7 +1,7 @@
---
title: 快慢通道 r2 非阻塞对话与任务卡
date: 2026-10-15
revision: r2-draft
revision: r2-draft.2
status: pending-review
owner: weichen
execution: design-only
@@ -10,12 +10,14 @@ parent: 2026-10-12-fast-slow-channel-display.md@r1.1
# 快慢通道 r2:非阻塞对话与任务卡
状态:**阶段 1–4 文稿已起草,待人工评审。** 本稿是已批准方案
状态:**阶段 1–4 已按评审意见修订,结论仍为未评审。** 本稿是已批准方案
[r1.1](2026-10-12-fast-slow-channel-display.md) 的增补候选。评审通过前,r1.1 仍是有效方案;
下文「拟取代」条款在阶段 4 批准后才生效。业务代码、模型试验、推送、PR、合入与部署均未授权。
授权依据:2026-10-15 用户确认独立兄弟分支,并确认本轮只产出阶段 1–5 文档、逐阶段评审。
Dev 任务分支 `feature/fast-slow-r2-nonblocking`,R0 `63e70d8b91ccb1691ce9b78a373e4e8bc9da24a2`。
Dev 任务分支 `feature/fast-slow-r2-nonblocking`。任务启动 R0
`63e70d8b91ccb1691ce9b78a373e4e8bc9da24a2`。修订前已 `task-sync`,同步基线
`692735e91d6a9ab07ddd3686feb60a56b270728a`(包含 `7a0f934`)。
实施计划见 [r2 实施计划](2026-10-15-fast-slow-r2-nonblocking-plan.md)。
## 1. 需求拆解
@@ -24,6 +26,7 @@ Dev 任务分支 `feature/fast-slow-r2-nonblocking`,R0 `63e70d8b91ccb1691ce9b7
保留现有视觉风格。中栏是一条连续对话,右栏是持续更新的任务卡。后台结果写回自己的卡片,
默认只给轻提示。用途选择留在任务卡里,用户可以继续聊天、稍后决定,或用一句话直接交代下一步。
右栏关闭、切到文件或窄屏时,同一张卡的阅读和操作改由中栏承担。
### 1.2 用户场景
@@ -32,33 +35,35 @@ Dev 任务分支 `feature/fast-slow-r2-nonblocking`,R0 `63e70d8b91ccb1691ce9b7
1. 11:04 上传说明书。中栏给出简短收件反馈。右栏立即出现一张材料整理卡。
2. 后台开始整理。同一张卡更新阶段和已经形成的要点。用户可以继续发消息。
3. 11:05 整理完成。右栏出现内容概览、完整整理结果、来源和可选下一步。中栏保持原有对话顺序。
4. 用户说「总结一下这份材料」。系统把要求关联到该材料,开始一次摘要任务,右栏显示它的进展。
4. 用户说「总结一下这份材料」。系统把要求关联到该材料。已有同范围请求时复用并显示进展;没有时才启动一次摘要任务。右栏显示它的进展。
5. 用户转而讨论别的问题。中栏继续当前话题。摘要完成后更新自己的卡片,并显示未读提示。
6. 用户查看摘要。在右栏读要点、展开全文或打开文件。需要追问时,把结果引用到对话后再提问。
6. 用户查看摘要。在右栏读要点、展开全文或打开文件。需要追问时,可以把结果引用到对话后再提问;不引用也可以问,但回答不得声称看过未带入的版本。
若第 4 步选择「先不选择」,用途区收起,材料整理结果仍可查,会话里没有挂起的前台回合。
若第 3 步出现的用途区选择「先不选择」,用途区收起,材料整理结果仍可查,会话里没有挂起的前台回合。
之后可以点「暂不处理 · 可随时继续」重新展开原选择区。
### 1.3 子需求
| 主题 | 用户可观察到的结果 |
|---|---|
| 栏职责 | 发言在中栏;后台进度、阶段成果和完整结果在同一张右栏任务卡;中栏只留关联入口 |
| 栏职责 | 发言在中栏。右栏「工作」可见时,后台进度、阶段成果和完整结果在同一张右栏任务卡,中栏只留关联入口。右栏关闭、切到文件或窄屏时,中栏展开同一张卡和操作 |
| 一张卡 | 一项后台工作从开始到结束保持同一身份、同一来源消息和同一材料 |
| 阅读层级 | 概览、工作详情、执行记录分层;过程文字、思考、工具和输出仍可展开查阅 |
| 进展 | 同一段流式文字更新原位置;阶段变化才新增阶段记录 |
| 阅读层级 | 概览、工作详情、执行记录对应 r1.1 的 L0–L3。可展开的是已保存且有权查看的公开摘要、工具名、授权参数和输出 |
| 进展 | 同一段流式文字更新原位置;阶段变化才新增阶段记录。工具开始和结束只进入活动行和执行记录 |
| 完成正文 | 展示可读要点和完整结果;没有可靠短摘要时说明结果已生成并给出入口 |
| 到达 | 原卡更新、未读加一、轻提示一次;对话历史、焦点和滚动位置保持不动 |
| 引用 | 用户主动把结果引用到输入区后,下一条提问才成为新的对话回合 |
| 选择 | 用途选项、补充要求和「先不选择」都在任务卡内,不占住会话 |
| 直接交代 | 语义清楚的材料用途指令直接启动对应工作,并关闭已被满足的选择 |
| 到达 | 原卡更新、未读加一、轻提示一次;对话历史、焦点和滚动位置保持不动。展开详情或完整结果,或显式标记已读后,未读才减少 |
| 引用 | 引用保证该结果版本进入下一回合。未引用时助手只可按权限查询,且不得声称看过未带入的内容 |
| 选择 | 用途选项、补充要求和「先不选择」都在任务卡内,不占住会话。暂不处理可以重新展开 |
| 直接交代 | 语义清楚的材料用途指令绑定该材料,复用已有同范围请求;没有时才启动工作,并关闭已被满足的选择 |
| 汇合 | 选择按钮和聊天消息进入同一个任务请求;重复提交看到已有进展 |
| 滚动 | 两栏各自滚动;只有点击关联入口才定位和高亮 |
| 时间 | 消息时间固定;卡片分别标创建、更新、完成;选择和阶段带事件时间 |
| 时间 | 消息时间固定;卡片分别标创建、更新、完成;选择和阶段带事件时间。完整时间戳不只有悬停 |
### 1.4 边界与非目标
纳入:信息归属、任务卡投影、进展去重、完成正文、到达通知、用途选择、任务请求幂等、
滚动、时间戳、存量事件的读取规则,以及这些行为的测试计划。
纳入:信息归属、任务卡投影、进展去重、完成正文、到达通知、已读与再次更新、用途选择、
暂不处理的重新展开、任务请求幂等、滚动、时间戳、存量事件的读取规则、安全展示边界,
以及这些行为的测试计划。
不纳入:
@@ -67,6 +72,7 @@ Dev 任务分支 `feature/fast-slow-r2-nonblocking`,R0 `63e70d8b91ccb1691ce9b7
- 视觉风格重做、新的颜色字号和第四栏。
- 在跑任务的动态改写。改变范围或要求重新生成时,建立新的结果版本。
- 部署、线上修复,以及 U3 质量线 `feature/fast-slow-u2-u3-plan` 的传输与工具流工作。
- 前台消息跨刷新、跨会话的 outbox 可靠性。作者私有草稿、服务端持久化、恢复鉴权和删除语义另立需求。
### 1.5 待澄清(不阻塞本稿结构)
@@ -74,28 +80,31 @@ Dev 任务分支 `feature/fast-slow-r2-nonblocking`,R0 `63e70d8b91ccb1691ce9b7
|---|---|---|
| 「语义十分清楚」由谁判定 | 先用确定性规则:卡片输入、显式任务引用、或与待选材料及用途词同时出现的指令 | 是否以后增加模型判断 |
| 存量 160 字摘要 | 历史卡保留已保存正文,并提供完整结果入口;新完成卡按本节规则生成 | 是否离线回填旧卡 |
| 引用是否为读取结果的前提 | 引用保证该结果版本进入本轮。未引用时只允许受权限约束的查询,并禁止声称看过未带入的内容 | 是否改为「不引用就不能读」 |
## 2. 需求评估
### 2.1 价值与现状
2026-10-15 对一次真实会话的只读核对,已经把现象对应到固定组合里的实现。
来源为 SELF:只读源码,没有改代码,没有调用模型。
修订文稿前又在 `task-sync` 之后重验行号。来源为 SELF:只读源码,没有改业务代码,没有调用模型。
核对对象:Dev R0 `63e70d8b91ccb1691ce9b78a373e4e8bc9da24a2` 物化后的组件
Backend `0a57853154e331cdb02a6a74ec2e13033b843e63`、
核对对象:Dev 同步基线 `692735e91d6a9ab07ddd3686feb60a56b270728a` 物化后的组件
Backend `80bb123c874cd9eb0e25f12ccd41e888f727a7e1`、
Frontend `5ab81432d10291e1885256293192bc96038fa061`、
Core `5773e74086791731059730bd3726dc8c9cd1381f`、
UI `e295caeef377a0e9588a3057d280864b2a011b71`、
Documents `46506aec34a8803d1b7f4de1a048de9dba591da2`。
Documents `0f06abd57c7bfa9e88dfea22e2a46719a7bfc5bf`(已含 Documents `origin/main`
`d668a3e0ac345dc80a72d15469f25918c4535ee6`)。
原稿记录的 Backend `0a57853154e331cdb02a6a74ec2e13033b843e63` 已被本次同步取代。
行号属于这次检出,后续提交移动后以当时文件为准。
| 现象 | 当前实现 | 符合度 |
|---|---|---|
| 协作进展重复 | `sub_loop.go` 每个 `text_delta` 发布累计文本前 80 字(约 210 行);`live.ts` `runEventsToTimeline`(约 244 行)把每条追加成「协作进展」 | 需调整后符合。事件可以留,展示要按任务归并 |
| 协作进展重复 | `runtime/sub_loop.go` 每个 `text_delta` 发布累计文本前 80 字(约 210 行);`live.ts` `runEventsToTimeline`(约 244 行)把每条追加成「协作进展」 | 需调整后符合。事件可以留,展示要按任务归并 |
| 右栏看不到完整结果 | `runmgr.go` 约 2241 行在摘要为空或为「完成」时 `truncate(fullText, 160)`。全文已在 `payload.Text` 和落库消息里 | 需调整后符合。读取已有全文即可,不必先提高模型质量 |
| 整理结束后出现新回复和选择卡 | `deliverNotices`(约 2536 行)经 `startNoticeRun`(约 2602 行)占住会话;约 2634 行要求汇报并立即 `confirm_choice`;`verify.go` 约 43 行对弱模型再强制一次 | 需调整后符合。这是行为变更,批准前不能动 |
| 已处理仍写「可自由输入」 | `AskHITL` 约 804 行只把一句 Markdown 放进投影,没有输入控件,处理后也不替换 | 需调整后符合 |
| 已处理仍写「可自由输入」 | `AskHITL` 约 805 行只把一句 Markdown 放进投影,没有输入控件,处理后也不替换 | 需调整后符合 |
| 两栏滚动位置奇怪 | `Conversation.tsx` 约 659 行用 `scrollsync.ts` 的滚动百分比带动右栏 | 需调整后符合 |
| 同一摘要像处理了两遍 | `material.go` `materialKey`(约 44 行)只用文件名和解析字数,没有「材料内容 + 用途 + 请求版本」这一任务请求身份 | 需调整后符合 |
@@ -105,12 +114,14 @@ Documents `46506aec34a8803d1b7f4de1a048de9dba591da2`。
| 项 | 判断 |
|---|---|
| 可行性 | 完整结果、事件和任务卡已经存在。增量 1 主要是投影、归并和滚动。增量 2 改完成通知、选择状态和请求幂等 |
| 成本 | 跨 Core、Backend、Frontend、UI 与 Dev gitlink。Documents 只承载方案。无新模型调用预算 |
| 可行性 | 完整结果、事件和任务卡已经存在。P0 改完成通知、选择状态、已读和请求幂等。P1 改进展归并、滚动、时间和面板整理 |
| 成本 | 跨 Core、Backend、Frontend、UI 与 Dev gitlink。Documents 只承载方案。无新模型调用预算。不新增 outbox 服务端存储 |
| 依赖 | 既有 ActivityCard、HITL、事件 seq、工件预览。内容身份沿用 r1.1 §8.3:内容 hash 与解析版本 |
| 在途重叠 | Dev `feature/fast-slow-u2-u3-plan` 及 Documents 同名远端分支在做 U3 r0.1–r0.6,会碰到 `runmgr.go`、`store.ts`、`live.ts`。本任务是兄弟分支,不堆叠、不暂停对方。合入前各自 `task-sync`,冲突按语义核验 |
| 风险 | 取消自动汇报会改变用户已经习惯的「做完会在对话里说一声」。轻提示和未读必须真实可达,否则结果会被漏看 |
| 行为面 | 增量 2 会改 `startNoticeRun` 提示和终轮兜底。交付规范要求真实模型前后对照。用户已说明该对照不是这些交互修复的前置条件,故计划中标 `NOT_RUN` 并写补救,不用「预期改善」代替证据 |
| 信息架构 | 原稿把中栏写成始终只留入口,与 DESIGN.md「右栏关闭或切到文件时中栏承担完整卡片与操作」以及 r1.1 R11 冲突。修订后两种可见性共用同一 taskId |
| 范围 | 原稿把前台排队的跨刷新恢复放进核心闭环。那会带出作者私有草稿、服务端持久化、恢复鉴权和删除语义。本轮拿掉,只保留后台任务和普通待选不占聊天队列 |
| 风险 | 取消自动汇报会改变用户已经习惯的「做完会在对话里说一声」。轻提示和未读必须真实可达,否则结果会被漏看。右栏关闭时若中栏没有完整操作,R11 会退步 |
| 行为面 | P0 会改 `startNoticeRun` 提示和终轮兜底。交付规范要求真实模型前后对照。用户已说明该对照不是这些交互修复的前置条件,故计划中标 `NOT_RUN` 并写补救,不用「预期改善」代替证据 |
### 2.3 与 r1.1 的拟取代条款
@@ -119,41 +130,47 @@ Documents `46506aec34a8803d1b7f4de1a048de9dba591da2`。
| r1.1 | r2 拟采用 |
|---|---|
| §9.1 多任务相继完成时,原卡先显示结果,父会话空闲后再合并汇报 | 只更新原卡,加未读和一次轻提示。不启动前台汇报回合 |
| §9.4 前台忙时沿用输入排队 | 前台正在生成时可以短暂排队。后台运行和普通待选卡不占聊天队列。已排队消息在切换会话或刷新后仍然可发送 |
| §9.4 前台忙时沿用输入排队 | 前台正在生成时可以短暂排队。后台运行和普通待选卡不占聊天队列。跨刷新、跨会话恢复排队消息不在本轮 |
| §5 右栏顺序「需要你处理 → 当前查看 → 其他进行中 → 新结果 → 已收纳」 | 收敛为「当前工作」和「工作历史」。新任务在上,历史按完成或处理时间倒序并默认折叠 |
| R10 完成后把结论回投到对话 | 右栏更新,用户用「引用结果到对话」决定是否带入下一回合 |
| §6.1「后台结束」默认在快通道给结论 | 快通道保持用户正在进行的对话。结果留在原任务卡 |
| R10 完成后把结论回投到对话 | 右栏更新。引用把结果版本带入下一回合;不引用时不得声称已读该版本。右栏不可见时,中栏展示同一张卡 |
| §6.1「后台结束」默认在快通道给结论 | 快通道保持用户正在进行的对话。结果留在原任务卡;右栏不可见时由中栏展示这张卡 |
r1.1 的其余已批准内容继续有效:四层阅读里 L3 执行记录仍保留、失败与成功分开、来源不编造、
更新不抢占正在阅读的文件、材料内容身份不用文件名加字数冒充。
更新不抢占正在阅读的文件、材料内容身份不用文件名加字数冒充、成果不是思维链、
右栏关闭与窄屏时主要能力完整(R11)。
## 3. 需求表
项目符合度依据第 2 节源码核对。处理结论在阶段 3 评审前均为待定;下表给出建议结论,供评审确认。
「纳入本增量」指 r2 实施计划中的增量,不表示现在可以写业务代码。
层级:P0 是核心非阻塞闭环;P1 是时间、归并和面板整理;「约束」必须保持,不单独排期。
| ID | 描述 | 符合度 | 优先级 | 可判定验收 | 依赖 | 建议结论 |
| ID | 描述 | 符合度 | 层级 | 可判定验收 | 依赖 | 建议结论 |
|---|---|---|---|---|---|---|
| NB01 | 中栏按发送顺序展示用户发言和助手对当前问题的回复;后台进度、阶段成果和完整结果不复制进中栏,只留关联入口 | 需调整后符合 | P0 | 材料整理的子任务日志不进入第一轮快速回复的执行记录。展开前台记录可见「已启动材料整理」,点击后打开同一任务 | 既有消息与 run 事件 | 纳入增量 1 |
| NB02 | 一项后台工作从开始到结束只维护一张任务卡,身份和触发消息、材料保持不变 | 需调整后符合;r1.1 R02 已有方向,完成通知目前会另起回合 | P0 | 走查场景 1–3 步右栏始终是同一张材料卡;刷新后仍是同一 ID | 任务登记 | 纳入增量 1 |
| NB03 | 概览、工作详情、执行记录三层可读。已保存的过程、思考、工具和输出可展开 | 需调整后符合 | P0 | 默认见名称、材料、状态、时间和当前事项;展开可见完整结果与执行记录。折叠不删除事件 | 既有事件回放 | 纳入增量 1 |
| NB04 | 同一段流式文字更新原位置;只有阶段变化才新增阶段记录 | 需调整后符合 | P0 | 用一段重复开头的进度事件回放,时间线里该段只占一行,文字随最后内容更新。原始事件仍在详细记录中可查 | `agent.progress` | 纳入增量 1 |
| NB01 | 中栏按发送顺序展示用户发言和助手对当前问题的回复。右栏「工作」可见时,后台进度、阶段成果和完整结果不复制进中栏,只留关联入口。右栏关闭、切到文件或窄屏时,中栏展开同一任务的完整卡片与操作 | 需调整后符合 | P0 | 右栏展开时,材料整理的子任务日志不进入第一轮快速回复。右栏关闭时,不打开右栏即可读摘要和依据、处理用途选择、打开文件,且与右栏是同一任务 ID | 既有消息与 run 事件 | 纳入增量 1 |
| NB02 | 一项后台工作从开始到结束只维护一张任务卡,身份和触发消息、材料保持不变 | 需调整后符合;r1.1 R02 已有方向,完成通知目前会另起回合 | P0 | 走查场景 1–3 步始终是同一张材料卡;刷新后仍是同一 ID | 任务登记 | 纳入增量 1 |
| NB03 | 概览、工作详情、执行记录三层可读,并映射 r1.1 L0–L3。可展开的是已保存、且当前用户有权查看的公开工作摘要、工具名、已授权参数和输出 | 需调整后符合 | P1 | 默认见名称、材料、状态、时间和当前事项;展开可见完整结果与执行记录。折叠不删除已保存的公开事件 | 既有事件回放 | 纳入增量 2 |
| NB04 | 同一段流式文字更新原位置。只有阶段变化才新增阶段记录。工具开始和工具结束只更新活动行并进入执行记录 | 需调整后符合 | P1 | 用一段重复开头的进度事件回放,时间线里该段只占一行。工具起止不增加阶段行。原始事件仍在详细记录中可查 | `agent.progress` | 纳入增量 2 |
| NB05 | 完成卡读取后台最终结果。没有可靠短摘要时显示「整理结果已生成,查看完整结果」 | 需调整后符合 | P0 | 完成卡正文能打开全文。开头是标题或表格时,概览不把截断标题当成摘要 | 已落库的子代理消息 | 纳入增量 1 |
| NB06 | 运行中的「当前发现」只收已经形成的实质结果。检索开场和工具调用只进入活动行或执行记录 | 需调整后符合 | P0 | 「我来检索」「正在调用工具」不出现在「已整理的要点」 | 阶段与工具事件 | 纳入增量 1 |
| NB07 | 后台完成时更新原卡、标记新结果、工作入口未读加一,并给出一次轻提示 | 需调整后符合;当前会 `claimConversation` 后启动通知回合 | P0 | 完成时中栏消息条数不变,滚动位置不变,输入焦点不变。提示含材料名,例如「《说明书》的材料整理已完成」 | 卡片与未读 | 纳入增量 2 |
| NB08 | 用户可以把结果引用到当前输入。引用可移除。发送后才成为新回合,并带上来源任务 | 符合度待核实:输入区尚无此引用标签 | P0 | 引用后提问出现在对话末尾,时间是发送时间,回答可以使用已完成结果而不再跑一遍同一摘要 | 任务结果版本 | 纳入增量 2 |
| NB09 | 用途选择放在所属任务卡底部,含单选或多选、补充输入、「按此处理」和「先不选择」 | 需调整后符合 | P0 | 选择出现时用户仍能发送无关消息并得到回复。推荐项有标识,且不会自动执行 | HITL 投影 | 纳入增量 2 |
| NB10 | 自由输入是卡片里的真实控件。处理后展示实际选择和补充要求,并与后续生成的完成状态分开 | 需调整后符合 | P0 | 处理后可见「已选择:简明摘要;重点:使用流程和技术参数」,同时后续任务仍显示自己的进行中或完成。失效的「可自由输入」不再出现 | `AskHITL` 投影 | 增量 1 先替换投影文案与历史;增量 2 完成非阻塞语义 |
| NB11 | 「先不选择」收起选择区,留下「暂不处理 · 可随时继续」,不催问、不自动重开 | 需调整后符合 | P0 | 收起后没有挂起的前台回合;刷新后仍是收起状态 | 选择状态持久化 | 纳入增量 2 |
| NB12 | 明确回答当前材料用途的发言,更新该任务要求并启动一次工作。其他问题按新话题处理,原选择保留 | 需调整后符合 | P0 | 「总结一下这份材料的摘要」绑定该材料并显示「已按你的要求开始整理摘要」。同时讨论无关问题时,原选择仍在 | 确定性绑定规则 | 纳入增量 2 |
| NB13 | 选择按钮和聊天消息汇合到同一任务请求。已有工作只显示进展。明确要求重新生成或改变范围时才建立新结果版本 | 需调整后符合 | P0 | 两个入口几乎同时提交,只产生一个摘要任务和一组结果文件。再次要求「重新生成」才出现新版本 | 内容 hash、用途、请求版本 | 纳入增量 2 |
| NB14 | 需要授权的操作继续等待授权,并且只阻止依赖该授权的工作。自由输入和「先不选择」不算同意 | 符合;危险确认已经独立。需保持 | P0 | 授权卡未处理时,无关对话仍可发送。两种放弃动作不会让被授权动作执行 | 既有 HITL | 纳入增量 2 |
| NB15 | 取消按滚动百分比联动。关联只在用户点击「查看关联任务」或「定位发起消息」时定位并高亮 | 需调整后符合 | P0 | 滚动中栏时右栏位置不变。点击入口后目标高亮。用户正在看旧卡时,新结果只显示「有 1 项更新」 | `scrollsync.ts` | 纳入增量 1 |
| NB16 | 右栏分当前工作与工作历史。当前工作含进行中、确实等待输入的任务、新到未查看的结果,新任务在上。历史默认折叠 | 需调整后符合 | P0 | 用途选择和选择历史留在所属任务卡内,不另堆「已处理」卡。阅读旧卡时卡片不因更新而自动排序、展开或跳转 | 卡片排序 | 纳入增量 2 |
| NB17 | 消息常驻显示时刻,跨天显示日期,悬停可见完整时间。卡片分别标创建、更新、完成。选择记录带提交时间 | 需调整后符合 | P0 | 后台更新不改变已有消息的时间。选择时间与后续任务的开始、完成时间彼此可区分 | 消息 `createdAt`、卡片时间 | 增量 1 固定消息时间并给卡片三个时间标签;增量 2 补选择记录时间 |
| NB18 | 右栏收起时,中栏附近显示「后台工作 N 项 · 新结果 M 项」,点击打开同一任务面板。窄屏用该面板的抽屉 | 需调整后符合;`ConversationWork` 已有收起摘要,需改成同一面板 | P0 | 收起、窄屏和右栏展开三者打开的是同一任务 ID,没有第二套详情 | 现有右栏 | 纳入增量 2 |
| NB19 | 前台生成中的短暂排队在切换会话或刷新后仍可发送。后台运行和普通待选不使聊天一直排队 | 需调整后符合;`outbox.ts` 目前只在内存中 | P0 | 刷新后排队消息仍在。材料整理进行中直接发送的新消息进入对话,而不是一直停在本地队列 | 会话占用与 outbox | 纳入增量 2 |
| NB20 | 升级后仍能阅读旧会话。重复进展按新规则折叠展示,原始事件还在。旧完成卡若只有 160 字摘要,概览标明这是当时保存的开头,并尽量链到已存全文 | 需调整后符合 | P0 | 打开含 80 次重复进展的历史会话,默认时间线没有 80 行相同开头;详细记录仍能按事件查看 | 旧事件只读 | 纳入增量 1 |
| NB06 | 运行中的「当前发现」只收已经形成的实质结果。检索开场和工具调用只进入活动行或执行记录 | 需调整后符合 | P1 | 「我来检索」「正在调用工具」不出现在「已整理的要点」 | 阶段与工具事件 | 纳入增量 2 |
| NB07 | 后台完成时更新原卡、标记新结果、工作入口未读加一,并给出一次轻提示 | 需调整后符合;当前会 `claimConversation` 后启动通知回合 | P0 | 完成时中栏消息条数不变,滚动位置不变,输入焦点不变。提示含材料名,例如「《说明书》的材料整理已完成」 | 卡片与未读 | 纳入增量 1 |
| NB08 | 用户可以把结果引用到当前输入。引用可移除。发送后才成为新回合,并带上被引用的结果版本。引用保证该版本进入本轮;未引用时不得声称看过未带入的内容 | 符合度待核实:输入区尚无此引用标签 | P0 | 引用后提问出现在对话末尾,时间是发送时间,回答可以使用该结果版本而不再跑一遍同一摘要。未引用的提问不把该版本写成已经读过,除非权限内查询实际读到并加以说明 | 任务结果版本 | 纳入增量 1 |
| NB09 | 用途选择放在所属任务卡底部,含单选或多选、补充输入、「按此处理」和「先不选择」。右栏不可见时,同一选择出现在中栏的同一张卡上 | 需调整后符合 | P0 | 选择出现时用户仍能发送无关消息并得到回复。推荐项有标识,且不会自动执行 | HITL 投影 | 纳入增量 1 |
| NB10 | 自由输入是卡片里的真实控件。处理后展示实际选择和补充要求,并与后续生成的完成状态分开 | 需调整后符合 | P0 | 处理后可见「已选择:简明摘要;重点:使用流程和技术参数」,同时后续任务仍显示自己的进行中或完成。失效的「可自由输入」不再出现 | `AskHITL` 投影 | 纳入增量 1 |
| NB11 | 「先不选择」收起选择区,留下「暂不处理 · 可随时继续」,不催问、不自动重开。点该提示重新展开原选择区并回到待选,不新建请求 | 需调整后符合 | P0 | 收起后没有挂起的前台回合;刷新后仍是收起状态。点提示后选项恢复,任务请求数不变 | 选择状态持久化 | 纳入增量 1 |
| NB12 | 明确回答当前材料用途的发言,绑定该材料并复用已有同范围请求;没有时才启动一次工作。其他问题按新话题处理,原选择保留 | 需调整后符合 | P0 | 第二次说「总结一下这份材料的摘要」不新开摘要任务,只显示已有进展。同时讨论无关问题时,原选择仍在 | 确定性绑定规则 | 纳入增量 1 |
| NB13 | 选择按钮和聊天消息汇合到同一任务请求。已有工作只显示进展。明确要求重新生成或改变范围时才建立新结果版本 | 需调整后符合 | P0 | 两个入口几乎同时提交,只产生一个摘要任务和一组结果文件。再次要求「重新生成」才出现新版本 | 内容 hash、用途、请求版本 | 纳入增量 1 |
| NB14 | 需要授权的操作继续等待授权,并且只阻止依赖该授权的工作。自由输入和「先不选择」不算同意 | 符合;危险确认已经独立。需保持 | 约束 | 授权卡未处理时,无关对话仍可发送。两种放弃动作不会让被授权动作执行 | 既有 HITL | 随增量 1 保持,不单独排期 |
| NB15 | 取消按滚动百分比联动。关联只在用户点击「查看关联任务」或「定位发起消息」时定位并高亮 | 需调整后符合 | P1 | 滚动中栏时右栏位置不变。点击入口后目标高亮。用户正在看旧卡时,新结果只显示「有 1 项更新」 | `scrollsync.ts` | 纳入增量 2 |
| NB16 | 右栏分当前工作与工作历史。当前工作含进行中、确实等待输入的任务、新到未查看的结果,新任务在上。历史默认折叠 | 需调整后符合 | P1 | 用途选择和选择历史留在所属任务卡内,不另堆「已处理」卡。阅读旧卡时卡片不因更新而自动排序、展开或跳转 | 卡片排序 | 纳入增量 2 |
| NB17 | 消息常驻显示时刻,跨天显示日期。完整时间戳除悬停外,键盘聚焦、触屏点按和屏幕阅读器也能得到(`time` 的 `datetime` 与含完整本地时间的可访问名称)。卡片分别标创建、更新、完成。选择记录带提交时间 | 需调整后符合 | P1 | 键盘、触屏和读屏得到的完整时间与悬停一致。后台更新不改变已有消息的时间。选择时间与后续任务的开始、完成时间彼此可区分 | 消息 `createdAt`、卡片时间 | 纳入增量 2 |
| NB18 | 右栏「工作」可见时中栏只留入口。右栏关闭、切到文件或窄屏时,中栏承担完整卡片与操作。窄屏用同一面板的抽屉 | 需调整后符合;`ConversationWork` 已有收起摘要,需改成同一面板,并在中栏补齐操作 | P0 | 收起、窄屏、文件入口和右栏展开打开的是同一任务 ID。右栏关闭时可以读摘要和依据、处理确认或用途选择、打开文件 | 现有右栏 | 纳入增量 1 |
| NB19 | 后台运行和普通待选卡不使聊天一直排队。前台生成中可以短暂排队。跨刷新、跨会话恢复不在本需求 | 需调整后符合;当前完成后通知回合会占住会话 | P0 | 材料整理进行中直接发送的新消息进入对话,而不是一直停在本地队列。刷新之后排队消息是否还在,不作为本需求的验收 | 会话占用 | 纳入增量 1 |
| NB20 | 升级后仍能阅读旧会话。重复进展按新规则折叠展示,原始事件还在。旧完成卡若只有 160 字摘要,概览标明这是当时保存的开头,并尽量链到已存全文 | 需调整后符合 | P1 | 打开含 80 次重复进展的历史会话,默认时间线没有 80 行相同开头;详细记录仍能按事件查看 | 旧事件只读 | 纳入增量 2 |
| NB21 | 后台失败时原卡进入失败状态,保留已保存的部分结果和原因,不启动汇报回合。未读与轻提示仍发生一次。对应 r1.1 R08、R17 | 需调整后符合;失败目前可能随通知回合出现 | P0 | 失败卡不显示成功完成。中栏消息条数不因失败汇报增加。已保存的部分结果仍可打开 | 原任务卡与 run 终态 | 纳入增量 1 |
| NB22 | 选择已过期或已处理时,界面刷新成服务端状态,旧选项不能再次提交。对应 r1.1 R07 | 需调整后符合;r1.1 已有方向,r2 选择改到卡内后须保持 | P0 | 服务端返回已处理或版本过期后,原选项不可提交,中栏与右栏状态一致 | 选择版本 | 纳入增量 1 |
| NB23 | 展开不得展示隐藏思维链、系统或开发者提示、凭据、原始请求载荷、未授权工具数据。展开不提升权限。成果不是思维链(r1.1 §7.3) | 需保持;r1.1 §7.3 已批准 | 约束 | 夹具含上述类别时,任务卡、中栏入口和引用标签都不可见这些内容 | 现有权限 | 随增量 1 保持,不单独排期 |
| NB24 | 已读、再次未读和暂不处理有稳定转换。已读仅在展开详情或完整结果,或显式标记已读时发生。未读按仍有未读结果版本的任务计数。新结果版本、重新生成和失败后的新尝试使该任务重新未读。正在阅读的卡只显示「有 1 项更新」 | 符合度待核实:未读与暂不处理尚无这一状态机 | P0 | 展开详情后该任务未读消失;仅出现在视口不消失。再次完成使未读恢复。点「暂不处理 · 可随时继续」回到待选且不新建请求 | 结果版本与选择状态 | 纳入增量 1 |
## 4. 方案设计
@@ -164,32 +181,36 @@ r1.1 的其余已批准内容继续有效:四层阅读里 L3 执行记录仍
| A. 只改样式和截断长度 | 重复行、自动回合和滚动联动还在 | 不采用 |
| B. 完成后仍自动追加一轮短回复 | 对话顺序仍会被后台打断 | 不采用 |
| C. 完成后完全无提示 | 容易漏看结果 | 不采用 |
| D. 右栏持续更新同一张卡,加未读和一次轻提示;选择留在卡内;对话只在用户引用或主动提问时继续 | 对齐第 1 节场景 | **推荐** |
| D. 右栏持续更新同一张卡,加未读和一次轻提示;选择留在卡内;对话只在用户引用或主动提问时继续;右栏不可见时中栏承担同一张卡 | 对齐第 1 节场景,并保持 R11 | **推荐** |
### 4.2 职责
```text
中栏 右栏
用户与助手发言,按发送顺序 当前工作(新在上)
前台回合的折叠过程 同一任务卡:概览 / 详情 / 执行记录
「已启动材料整理」→ 打开该任务 选择、补充要求、选择历史
文件打开入口 工作历史(默认紧凑行)
右栏收起时的紧凑提示 文件页仍只做列表和预览
右栏「工作」可见时
中栏:用户与助手发言;前台回合的折叠过程;「已启动材料整理」→ 打开该任务;文件打开入口
右栏:当前工作(新在上);同一任务卡;选择与选择历史;工作历史
右栏关闭、切到「文件」或窄屏时
中栏:除上述发言外,展开同一 taskId 的完整卡片与操作(摘要、依据、选择、打开文件)
文件入口:仍只做列表和预览
```
异步状态只有一个所有者:服务端任务快照。前端按事件 seq 更新,过期事件丢弃。
中栏入口和右栏卡片读取同一任务 ID,不各算一份摘要。
中栏入口、中栏展开卡和右栏卡片读取同一任务 ID,不各算一份摘要。
### 4.3 任务卡三层
### 4.3 任务卡与 r1.1 四层阅读
| 层级 | 默认展示 |
|---|---|
| 概览 | 任务名称、关联材料、状态、创建/更新/完成时间,以及当前在做什么或已经得到什么 |
| 工作详情 | 内容要点、完整结果、依据、范围、文件、选择与补充要求 |
| 执行记录 | 已保存的过程文字、思考、工具及输出,默认折叠 |
| r2 卡片层 | r1.1 | 默认展示 |
|---|---|---|
| 概览 | L0 一行汇总加 L1 工作摘要 | 任务名称、关联材料、状态、创建/更新/完成时间,以及当前在做什么或已经得到什么 |
| 工作详情 | L2 阶段与依据 | 内容要点、完整结果、依据、范围、文件、选择与补充要求 |
| 执行记录 | L3 执行记录 | 已保存且当前用户有权查看的公开过程、工具名、已授权参数和输出,默认折叠 |
不在任何一层展示:隐藏思维链、系统或开发者提示、凭据、原始请求载荷、未授权工具数据。
展开不提升权限。这是 r1.1 §7.3「成果不是思维链」在 r2 的保持项(NB23)。
运行时活动行使用真实阶段,例如「已提取文档文字」「正在整理内容结构」。
「已整理的要点」只接收已经形成的实质结果。工具名和「我来检索」留在执行记录。
「已整理的要点」只接收已经形成的实质结果。工具名和「我来检索」留在活动行或执行记录,不进入要点。
完成时概览切到「整理结果」。正文来自后台最终消息的结构化要点;要点缺失时显示
「整理结果已生成,查看完整结果」,并链到已保存全文。实现上停止把全文开头 160 字写入用户可见摘要。
@@ -197,20 +218,32 @@ r1.1 的其余已批准内容继续有效:四层阅读里 L3 执行记录仍
### 4.4 进展归并
`agent.progress` 继续可以高频产生,原始事件不删。展示层为每个子任务维护一条「当前文字」:
同一文本流的后续累计内容替换这一条。阶段、工具开始和工具结束使用单独的阶段记录。
同一文本流的后续累计内容替换这一条。阶段变化才新增阶段记录。
工具开始和工具结束只更新活动行,并记入执行记录,不新增阶段记录。
回放与实时使用同一归并规则,避免刷新后再次刷出重复行。
### 4.5 到达与引用
### 4.5 到达、已读与引用
| 转换 | 规则 |
|---|---|
| 变为未读 | 该任务出现新的结果版本:首次完成、重新生成、失败后的新尝试。未读数按仍有未读结果版本的任务数计,不按事件条数计 |
| 变为已读 | 用户展开该卡的工作详情或完整结果,或显式标记已读。卡片只是出现在视口,不算已读 |
| 阅读中又更新 | 不自动标已读,不改变排序、展开和滚动。卡上显示「有 1 项更新」。用户再次展开新版本后才标已读 |
| 暂不处理 | 写入 `deferred` 并收起选择区。点「暂不处理 · 可随时继续」回到待选并展开原选项,不新建请求。选择已过期时改为刷新服务端状态,不恢复旧选项 |
| 引用 | 保证被引用的结果版本进入下一条用户消息的上下文。它不是助手读取结果的唯一前提 |
后台完成时:
- 原任务卡写入结果,标记「新结果」。
- 工作入口未读数加一。
- 工作入口未读数按任务加一。
- 轻提示一次,带材料名。
- 不插入历史消息,不追加助手长回复,不移动焦点,不改变滚动位置。
「引用结果到对话」在输入区放一个可移除标签。用户发出下一条消息时,该消息成为普通回合,
并记录被引用的任务和结果版本。助手回答相关问题时可以读取已经完成的结果。
并记录被引用的任务和结果版本。助手回答相关问题时可以读取这个已经完成的版本。
没有引用时,助手只可通过当前用户已有权限的任务结果查询读取。回答不得写成「我已看过该版本」,
除非这次查询实际读到了它,并说明读到的是哪一版。
多个任务同时完成时,每张卡各自更新,未读按任务计数,轻提示可以合并成一条计数,
仍然不启动汇报回合。
@@ -236,6 +269,7 @@ r1.1 的其余已批准内容继续有效:四层阅读里 L3 执行记录仍
- 互斥方案用单选。可以组合的事项用多选,并写明「可多选」。
- 推荐标记只是标识。
- 「先不选择」写入选择状态 `deferred`,选择区收起为「暂不处理 · 可随时继续」。
- 点该提示重新展开原选择区,状态回到待选,不新建任务请求。
- 选择历史保留选项、补充要求、提交时间和后续工作结果。
- 「已选择」与「生成完成」是两条状态。
@@ -248,8 +282,8 @@ r1.1 的其余已批准内容继续有效:四层阅读里 L3 执行记录仍
该材料的用途。规则至少同时识别材料指向和用途动作。无法同时满足时,只澄清关联,不静默绑定。
任务请求键包含材料内容 hash、解析版本、用途和请求版本。选择按钮与聊天消息使用同一键。
已有未完成或已完成且范围相同的请求时,展示其进展,不另起一份。用户明确要求重新生成或
改变范围时,请求版本递增,保留旧结果。
已有未完成或已完成且范围相同的请求时,展示其进展,不另起一份。重复的明确指令也走这条规则,
不再次启动工作。用户明确要求重新生成或改变范围时,请求版本递增,保留旧结果。
`materialKey` 继续可以存在于受控元数据,供旧客户端识别;用户默认卡身不展示内部键。
内容身份以 hash 和解析版本为准,与 r1.1 §8.3 一致。
@@ -262,23 +296,27 @@ r1.1 的其余已批准内容继续有效:四层阅读里 L3 执行记录仍
删除中栏滚动百分比到右栏的写入。`flashElement` 只在用户点击定位后使用。
用户停留在某张历史卡时,新结果不改变排序、展开状态和滚动位置,只显示「有 1 项更新」。
消息时间来自消息创建时间,后台卡更新不回写它。跨天显示日期,悬停显示完整时间戳。
消息时间来自消息创建时间,后台卡更新不回写它。跨天显示日期。
完整时间戳有四条路径:指针悬停、键盘聚焦、触屏点按、屏幕阅读器。
实现使用 `time` 元素的 `datetime`,可访问名称包含完整本地时间。
具体控件在阶段 5 确认,只用 `@ui` 已有原语,不新增私有样式。
卡片显示「创建」「更新」「完成」。选择记录显示「11:09 已选择:简明摘要」。
阶段和执行记录显示事件时间。正文流式输出不逐段显示时间。
右栏收起时的紧凑提示和窄屏抽屉都打开同一任务面板。
右栏「工作」可见时,中栏只留短入口。右栏关闭、切到文件或窄屏时,中栏展开同一任务的完整卡片与操作。
收起提示和窄屏抽屉打开的也是这一任务面板。
### 4.9 失败与存量
| 情况 | 表现 |
|---|---|
| 后台失败 | 原卡进入失败状态,保留已保存的部分结果和原因。不启动汇报回合。未读与轻提示仍发生一次 |
| 选择已过期或已处理 | 刷新成服务端状态。过期选项不能再次提交 |
| 重复点击 | 同一请求键只执行一次,按钮进入已提交 |
| 刷新与断线 | 卡片、选择状态、未读和已排队消息从服务端恢复。连接提示不改写业务终态 |
| 旧的重复进展 | 默认按 4.4 折叠;详细记录按原始 seq 查阅 |
| 旧的 160 字摘要 | 概览标明这是当时保存的开头,并链到已存全文。不把旧摘要改写成新的模型结果 |
| 无全文可链 | 显示「当时只保存了开头,完整结果不可用」 |
| 情况 | 表现 | 需求 |
|---|---|---|
| 后台失败 | 原卡进入失败状态,保留已保存的部分结果和原因。不启动汇报回合。未读与轻提示仍发生一次 | NB21 |
| 选择已过期或已处理 | 刷新成服务端状态。过期选项不能再次提交 | NB22 |
| 重复点击 | 同一请求键只执行一次,按钮进入已提交 | NB13 |
| 刷新与断线 | 卡片、选择状态和未读从服务端恢复。连接提示不改写业务终态。前台排队消息的跨刷新恢复不在本轮 | NB19 的排除项 |
| 旧的重复进展 | 默认按 4.4 折叠;详细记录按原始 seq 查阅 | NB20 |
| 旧的 160 字摘要 | 概览标明这是当时保存的开头,并链到已存全文。不把旧摘要改写成新的模型结果 | NB20 |
| 无全文可链 | 显示「当时只保存了开头,完整结果不可用」 | NB20 |
### 4.10 数据与权限
@@ -287,21 +325,26 @@ r1.1 的其余已批准内容继续有效:四层阅读里 L3 执行记录仍
引用只携带当前用户已经能阅读的任务结果版本。
不新增跨项目读取。执行记录的可见性保持现有权限,展开不提升权限。
公开投影排除隐藏思维链、系统或开发者提示、凭据、原始请求载荷和未授权工具数据。
不新增前台 outbox 的服务端记录,也不定义作者私有草稿的保存、恢复和删除。
### 4.11 待验证假设
| 假设 | 验证 | 若失败 |
|---|---|---|
| 最终消息里能够稳定抽出要点 | 增量 1 用已保存子代理消息做投影测试 | 没有要点就用诚实占位,不回退到截断开头 |
| 确定性绑定能覆盖「总结一下这份材料」这类句子,同时不误绑无关消息 | 增量 2 的语句样本,含无关话题和含糊句 | 含糊句只澄清。不在未批准时改成模型判断 |
| 去掉自动汇报后,轻提示足够让用户找到结果 | 阶段 7 的浏览器走查 | 调整提示位置,仍不恢复自动长回复 |
| 确定性绑定能覆盖「总结一下这份材料」这类句子,同时不误绑无关消息 | 增量 1 的语句样本,含无关话题、含糊句和重复的明确指令 | 含糊句只澄清。重复明确指令复用已有请求。不在未批准时改成模型判断 |
| 去掉自动汇报后,轻提示足够让用户找到结果;右栏关闭时中栏卡片同样可达 | 阶段 7 的浏览器走查 | 调整提示位置或中栏展开,仍不恢复自动长回复 |
## 5. 验收场景
主场景即 1.2。边界同时覆盖:多个任务同时完成、右栏关闭、刷新、重复点击、旧选择过期、后台失败。
主场景即 1.2。边界同时覆盖:多个任务同时完成、右栏关闭、切到文件、刷新、重复点击、
重复的明确指令、旧选择过期、后台失败、暂不处理后再展开、未读与再次更新。
判据:进展不刷重复行;完整结果能读到;选择不锁住无关对话;同一摘要只执行一次;
结果到达不改变消息顺序;历史记录的是用户实际决定。
结果到达不改变消息顺序;历史记录的是用户实际决定;右栏不可见时中栏能完成阅读、选择和打开文件;
排除项不会出现在展开内容里。
这些场景在本稿阶段是计划,状态 `NOT_RUN`。设计文档的保存不表示场景已通过。
@@ -309,10 +352,21 @@ r1.1 的其余已批准内容继续有效:四层阅读里 L3 执行记录仍
| 阶段 | 对象 | 结论 | 评审人 | 时间 | 依据 |
|---|---|---|---|---|---|
| 1 需求拆解 | 本稿 §1 | 未评审 | — | — | 待人工确认与原始意图一致 |
| 2 需求评估 | 本稿 §2 | 未评审 | — | — | 待人工确认取舍与 U3 并行方式 |
| 3 需求表确认 | 本稿 §3 NB01–NB20 | 未评审 | — | — | 待人工确认范围与验收条件 |
| 4 方案设计 | 本稿 §4 | 未评审 | — | — | 待人工批准后,拟取代条款才生效 |
| 5 实施计划 | [实施计划](2026-10-15-fast-slow-r2-nonblocking-plan.md) | 未评审 | — | — | 待人工批准后才可写业务代码 |
| 1 需求拆解 | 本稿 §1 @ r2-draft.2 | 未评审 | — | — | 待人工确认与原始意图一致 |
| 2 需求评估 | 本稿 §2 @ r2-draft.2 | 未评审 | — | — | 待人工确认取舍与 U3 并行方式 |
| 3 需求表确认 | 本稿 §3 NB01–NB24 | 未评审 | — | — | 待人工确认范围与验收条件 |
| 4 方案设计 | 本稿 §4 @ r2-draft.2 | 未评审 | — | — | 待人工批准后,拟取代条款才生效 |
| 5 实施计划 | [实施计划](2026-10-15-fast-slow-r2-nonblocking-plan.md) | 未评审 | — | — | 待阶段 1–4 通过后单独评审;未授权写业务代码 |
### 6.1 修订记录
| 项 | 内容 |
|---|---|
| 对象 | Dev `7b87e03`、Documents `3a43ce6` 上的 r2-draft |
| 意见 | 阶段 1–4 建议「需修改」,不是拒绝。阶段 5 未评审 |
| 来源 | SELF。智能体评审不能替代人工阶段批准 |
| 本稿 | r2-draft.2。阶段结论保持未评审 |
| 裁定 | 引用是保证上下文,不是读取结果的唯一前提。已读以展开详情、完整结果或显式标记为准,视口曝光不算。这两项仍可在人工评审时改 |
| 同步 | 修订前 `task-sync` 到 Dev `692735e`。该提交包含评审提到的 `7a0f934`。Documents `origin/main` 为 `d668a3e`。§2.1 行号已按 Backend `80bb123` 重验 |
源码核对:SELF,2026-10-15,对象见 §2.1。真实模型、浏览器和部署:`NOT_RUN`。
+1 -1
View File
@@ -18,7 +18,7 @@
运行卡呈现状态、已完成工作、当前发现与剩余项;四层阅读、阶段成果、来源、异常恢复及 U1–U4。
2026-10-12 方案设计已批准(阶段 1–4);首批仅 U1;[U1 实施计划 r1](2026-10-12-fast-slow-channel-display-u1-plan.md) 待阶段 5 批准;业务实施和运行验收 NOT_RUN。
候选增补 [r2 非阻塞对话与任务卡](2026-10-15-fast-slow-r2-nonblocking.md) 与
[r2 实施计划](2026-10-15-fast-slow-r2-nonblocking-plan.md) 已起草,状态为待评审。
[r2 实施计划](2026-10-15-fast-slow-r2-nonblocking-plan.md) 已修订为 r2-draft.2,阶段结论仍为未评审。
评审通过前 r1.1 仍然有效,r2 不取代已批准条款,也不授权业务代码。
Generative UI 方向已收口(U1–U7 全部落地,2026-10-12):[使用说明与评测记录](2026-10-12-generative-ui-usage-and-evaluation.md)(final);