Why: User authorized stage-5 start; record plan status for executors. Evidence: Chat authorization "开始"; no runtime tests. Impact: Documents proposal status only. Refs: 2026-10-12-fast-slow-channel-display-u1-plan.md
11 KiB
title, date, revision, status, owner, execution, parent
| title | date | revision | status | owner | execution | parent |
|---|---|---|---|---|---|---|
| 快慢通道展示 U1 实施计划 | 2026-10-12 | r1 | approved | weichen | implementation | 2026-10-12-fast-slow-channel-display.md@r1.1 |
快慢通道展示 U1 实施计划 r1
For agentic workers: 按本计划逐工作项实施;每项先写失败测试再改实现。规格依据主方案 r1.1。阶段 5 已于 2026-10-12 经用户「开始」批准;批准不等于推送/合入授权。
Goal: 统一后台任务真实状态语义,用 L1 精炼骨架替换「原始指令占主视图」,使失败不再显示为完成,并为后续 U2 快照契约留下兼容字段草图。
Architecture: 服务端在建卡/终态时写入精炼 Body 与正确 CardStatus;UI 按状态灯/状态词渲染;旧 done+danger 客户端兼容映射为失败。不引入持久 TaskSnapshot、不按任务路由 agent.progress、不发布阶段 findings(属 U2/U3)。
Tech Stack: Go(Core/Backend)、React+TypeScript(UI/Frontend)、既有 ActivityCard / UINode / cardsvc 事件流。
Spec: 快慢通道展示与动态工作摘要方案 r1.1 §4 R03-a、§7.1、§10.1、§14 U1 出口白名单。
Global Constraints
- 首批仅 U1;禁止顺手实现 U2/U3 范围(材料内容 hash、持久快照、检查点摘要、HITL 双入口完备)。
- 颜色/圆角/字号只消费
@ui/tokens.css;动效只用mk-*;折叠用 Collapsible。 - 证据经
CMD=… make evidence写入任务卡;声明通过须标 SELF/GATE。 - 跨仓顺序:Core(若有契约)→ Backend → UI → Frontend → Dev gitlink 组合
make test。 - 现有「停止」按钮语义不在本增量改名为「仅停前台」;不暴露暂停/独立取消/续跑。
Review Focus
- 失败卡若仍为
done,用户会当成成功收纳——须CardFailed或等价失败灯。 - 建卡若仍塞入 task 原文,用户会把指令当进度——须 L1 骨架。
- 材料去重若仍只认
CardDone,改为CardFailed后可能卡死重试门禁——须同步测试。 - 快通道在登记前说「已启动」——须与真实登记/开跑事件对齐。
CurrentTaskCard(plan/todos)与后台 progress 卡同目标叠卡——U1 须定义合并或降噪规则,避免双标题。
0. 范围与非目标
纳入(映射需求)
| 需求 | U1 验收子集 |
|---|---|
| R01 | 简单问答无空进度卡;复杂任务短答可含已确认范围与后台真实状态 |
| R02 | 已登记任务有稳定卡对象;未登记不显示「已启动」 |
| R03-a | L1 骨架 + 诚实无发现占位;不验收运行中真实发现 |
| R08 | 失败 ≠ 成功灯;状态词「执行失败」 |
| R10 | 完成卡骨架(结论/要点/缺项/入口);完备来源与版本定位可留 U3 |
| R13 | 守护测试通过;状态不只靠颜色(沿用 StatusLamp 形状) |
排除
见主方案 §14「明确排除」。另:不改 CancelRun 父句柄行为;不改 Surface 抢占策略(属 U2/U4)。
与 CurrentTaskCard 的合并规则(U1)
- 后台
CardKindProgress卡是慢通道权威对象。 - 若同一会话同时存在前台
plan/todos的CurrentTaskCard与后台 progress 卡:右栏「工作」优先列出 progress 卡;CurrentTaskCard仅在无后台 progress 卡且 plan/todos 非空时展示。 - 不在 U1 把 plan steps 写入后台卡 Body。
1. 工作项与文件
W1 — Core:精炼摘要契约草图与旧卡映射说明
Files:
- Modify:
modules/core/activity.go(若增加可选字段)或新增modules/core/task_summary.go - Test:
modules/core/activity_test.go或同目录新测
内容(最小):
// TaskSummaryView 是 U1 写入 ActivityCard.Body 的权威语义草图;
// 完整 TaskSnapshot(findings/revision/streamScope)留待 U2。
type TaskSummaryView struct {
Title string // 业务动宾短标题
Focus string // 正在做什么,≤2 行
FindingsNote string // U1:无成果时固定诚实文案;有结构化 findings 属 U3
Remaining string
NextStep string
OutcomeLine string // 完成后的结论一行;运行中可空
}
可选:在 ActivityCard 增加 Summary *TaskSummaryView \json:"summary,omitempty"``;Body 仍为旧客户端回退投影,新客户端优先读 Summary。若为降低跨仓面,U1 可仅约定 Body 的 Markdown/KV 形状而不加字段——但须在 Core 注释或本计划冻结 Body 键名:
| KV 键 | 含义 |
|---|---|
| 状态 | 排队中 / 进行中 / 已完成 / 执行失败 |
| 正在做 | Focus |
| 当前发现 | FindingsNote(U1 占位或完成后要点摘要) |
| 剩余 | Remaining |
| 下一步 | NextStep |
- 冻结 Body 键名或
Summary字段二选一,写入 Core 并单测序列化往返 - 文档注释标明 findings[] 属 U2/U3
- Commit:
docs(core): freeze U1 task summary body contract
W2 — Backend:建卡/终态状态与精炼 Body
Files:
- Modify:
modules/backend/internal/runmgr/runmgr.go(createBackgroundCard~1942、promoteQueuedCard~1970、finishBackgroundCard~1992) - Modify:
modules/backend/internal/runmgr/material_test.go(及同类依赖CardDone+danger的测试) - Test: 新增
modules/backend/internal/runmgr/background_card_test.go
当前问题(源码):
// create:Body 首节点 = truncate(task, 400)
// finish:SetStatus(..., CardDone, tone) 且失败 tone=danger、状态行仍写「已完成」
目标行为:
func backgroundRunningBody(focus string, kv [][2]string, statusLabel string) []core.UINode {
return []core.UINode{
{Type: core.UIMarkdown, Markdown: "尚无阶段结论,正在读取材料"},
{Type: core.UIKV, KV: append(append([][2]string(nil), kv...),
[2]string{"状态", statusLabel},
[2]string{"正在做", focus},
[2]string{"当前发现", "尚无阶段结论"},
[2]string{"剩余", "待任务进展后更新"},
[2]string{"下一步", "继续处理已登记工作"},
)},
}
}
// finish 成功:CardDone + tone ok;状态「已完成」;Markdown = 结论骨架
// finish 失败:CardFailed + tone danger;状态「执行失败」;保留已有可读摘要
- 失败测试:
finishBackgroundCard在err != nil时Status==CardFailed且 Body 状态键 ≠「已完成」 - 失败测试:
createBackgroundCardBody Markdown 不含原始 task 长指令(可用固定长 task 断言不出现) - 实现最小改动;
promoteQueuedCard只更新状态键为「进行中…」 - 更新
material_test:成功路径仍等CardDone;失败/重试路径认CardFailed或释放materialActive - 快通道诚实:spawn/登记路径日志与用户可见文案——仅在
Create成功后可称「已登记」;仅在子 run 启动后可称「进行中」(检查spawnBackground*/ material 入口提示,必要时改 system 提示片段;不做阶段发现生成) - Commit:
fix(backend): map background card fail to CardFailed and use L1 body
W3 — UI:状态灯与旧卡兼容
Files:
- Modify:
modules/ui/src/ActivityCardView.tsx(StatusLamp) - Test: 既有 UI 测试或新增
ActivityCardView测例;跑design-guard.test.ts
目标:
// done → 完成灯;failed → 失败灯(已有)
// 兼容:status===done && tone==='danger' → 按失败灯展示,title「执行失败(兼容)」
- 失败测试:
done+danger渲染失败形状灯,不渲染lamp-ok - 实现兼容映射;不新增裸色值
pnpm test/ 仓内 UI 测试目标通过- Commit:
fix(ui): treat done+danger progress cards as failed
W4 — Frontend:工作区排序与空卡
Files:
- Modify:
modules/frontend/src/components/Workbench.tsx(CurrentTaskCard展示条件) - Modify: 若 Inbox 过滤依赖 status,核对
store.ts对failed的分区(完成区 vs 进行中) - Test: 前端既有测试或最小组件测
目标:
-
存在
kind===progress && status===active(或排队文案)时隐藏与同会话抢注意力的空CurrentTaskCard(按 §0 合并规则) -
failed卡进入可收纳/结果区逻辑与done区分(失败可收纳但不显示成功语义) -
简单问答路径不因误触发材料整理产生空卡——若属既有路由,仅加回归断言「无附件无后台登记时 progress 卡数为 0」
-
实现合并规则
-
回归:无后台任务时 plan 仍可显示
-
Commit:
fix(frontend): prefer progress cards over duplicate CurrentTaskCard
W5 — Dev 组合与文档收口
Files:
-
Modify: Dev gitlink(Core/Backend/UI/Frontend 精确 SHA)
-
Modify: 实施任务卡证据段;主方案进展指针(若本增量合入时)
-
Test: 工作区根
make test、make build -
各组件 PR 顺序合入或同批组合验证
-
Dev
make test+make build;evidence 写入 -
更新主方案「规划进展」:U1 实施状态(仅在真实合入后)
2. 测试与环境
| 层 | 命令/方法 | 证明什么 |
|---|---|---|
| 单元 | Backend go test ./internal/runmgr/…;Core 序列化;UI StatusLamp |
状态映射、Body 骨架、兼容灯 |
| 守护 | UI/Frontend design-guard.test.ts |
无新增裸色值/私有 keyframes/行内字号 |
| 组合 | Dev make test、make build |
gitlink 组合可编译可测 |
| 手工冒烟(SELF) | 本地起服务:发材料看建卡;制造子任务失败看灯;简单问答无空卡 | U1 白名单场景 |
| 真实模型阶段成果 | NOT_RUN / 不在 U1 | — |
| 浏览器窄屏全矩阵 | NOT_RUN / 属 U4 | — |
被测对象:各仓 PR HEAD;组合声明须含精确 SHA。
3. 完成条件
- U1 出口白名单全部可判定项有 SELF 或 GATE 证据。
- R03-a 有测例;无人用「五问完整」拒绝 U1。
- 材料整理去重/重试在
CardFailed下仍可再次登记(或文档说明与测例固定行为)。 - 无 U2/U3 范围代码混入同一变更集(审 Diff)。
4. 停止与回退条件
- 失败状态与存储不一致(卡显示失败但去重门禁认为仍在跑,或相反)→ 停止合入,修 W2/材料门禁。
- 新旧客户端之一崩溃或空白卡 → 回退 Summary 字段改动,保留 Body 回退投影。
- 发现实现滑入持久快照/检查点摘要 → 拆出变更,不进本 PR。
- DESIGN 守护失败 → 先改令牌消费再继续。
回退策略:回退受影响展示映射与 Body 生成;不删除已保存 run 结果。
5. 依赖顺序与责任
W1 Core 契约(可选字段或 Body 键冻结)
→ W2 Backend 建卡/终态
→ W3 UI 灯兼容
→ W4 Frontend 工作区
→ W5 Dev gitlink + 组合测试
责任人:实施阶段指定;需求/评审:weichen。
预估:单增量跨 4 仓,以状态映射 + Body 重排为主,不含模型评测费用。
6. 计划评审状态
| 项 | 状态 |
|---|---|
| 关联方案 | r1.1 设计已批准;首批仅 U1 |
| 本实施计划 | 已批准(2026-10-12,用户「开始」) |
| 业务代码 | 实施中:feature/fast-slow-display-u1 |
| 推送/PR/合入 | 未授权(完成自检后另请) |
首选动作已执行:make task-start NAME=feature/fast-slow-display-u1,按 W1→W5 推进;设计任务卡可在文档 PR 合入后 task-close。