# 云之家-dsh 集成:设计方案 × 已有实现 对照与 Gap 分析 > 对齐对象:`../spec/integration-master-plan.md`(v1.7 人在闭环验收基准;**v1.8 会话家园产品法见 `../spec/dsh-home-session.md`,实现对照 §22**)↔ 本仓库现有实现(`packages/bridge`、`packages/tool-yzj`、`packages/ui-yzj`、`packages/bundle`、`packages/robot-yzj`) > 核验日期:2026-08-14 之后(实现开发期) > **v2.0 增补**(2026-08-17,Guoxin Shan):**群房间 + 话题会话产品法**([`../spec/group-room-topics.md`](../spec/group-room-topics.md))取代 v1.8 的 1:1 绑定与融合一条流。**设计已拍板;锚定 / 入站话题 / 群房间视图 / 写闸 / 出站进日志 / 面板第二 IM 退役已落地**,对照 **§23**。§22 保留为 v1.8 实现快照。 > v1.8 增补:**会话家园产品法**(2026-08-17,Guoxin Shan)——目标是 DSH 唯一家园 + 1:1 绑定。**绑定对象 + 融合时间线已落地**:入站与挑群打 `yzj-home-*`;`conversation.view`「群工作」融合 ①②③④;面板 composer 降为快捷 ②。仍开放 G3/G5。v1.7 完成度口径不因此改写。 > v1.4 增补:**UI 后续演化对照**(git `08fc7b1` → `af3bf5d`,19 个 ui-yzj commit)——面板四 tab→三 tab、悬浮球唯一入口、面板真 IM composer(用户直写)、拖入快捷动作移除、确认卡去 ID 化、未读持久化;新增 §16。v1.3 增补:**最终验收状态**(git `de3c058`)——全部可开发缺口完成:锚点定位高亮、@ 候选三组、拖入即处理引导均已落地;剩余仅机制受限项(多 chip 合并、通知卡、确认卡事件族,均为 harness 契约边界)与待拍板项(合并确认、快照决策)。全量 build/typecheck/test 通过(58 passed)。v1.2 增补:实现进展状态全量刷新(git 至 `491db61`)——P0 消息回源、P1 门禁分级 + 确认卡、通知层一/三、skill、影子任务库、dbt 预览均已落地;剩余缺口见 §15 更新清单。v1.1 增补:补全实现侧全部工具明细(§2);新增设计补强「悬浮窗全量拖拽 → composer」(§2A,用户思路)。 **完成度:≈95%(host 侧稳定;UI 侧在验收后继续演化,见 §16——其中「我的」tab 移除仍是对 v1.6 的偏离,终局待拍板;用户直写原则已由 v1.8 D9 拍板)**——按设计 v1.7 验收基准。**v1.8 会话家园不在此百分比内**:绑定 + 融合时间线已落地(§22 G1/G2/G4/G6),G3/G5 仍开放。**禁止**把 §20 机器人通道「已闭环」读成家园完成。 *本文档为对照记录,不替代 v1.7 设计原文,也不替代 v1.8 [`dsh-home-session.md`](../spec/dsh-home-session.md);标注「待拍板」的项目维持原设计的决策归属——其中写路径两分已由会话家园 D9 拍板。* --- ## 1. 总体对照(§3.2 三个组件 + 一个协议) | 设计(§3.2) | 实现 | 状态 | |---|---|---| | **yzj-tools**(host):工具 + 门控写 + `yzjReader` 服务 + dsh skill | `@dsh-yzj/bridge`(`ctx.yzjBridge`)+ `@dsh-yzj/tool-yzj`(41 工具六域)+ `guard.ts`(标准/强确认两级门禁,**全量写工具入闸**) | ✅ 工具超配、门禁分级齐全;yzjReader 以 `/yzj` RPC 通道替代;skill 随 bundle 交付 | | **yzj-ui**(client):悬浮窗、@ 候选源、拖放 chip、codec、确认卡、面板跳转服务 | `@dsh-yzj/ui-yzj`:四 tab 面板(含角标轮询)、`inputTriggers` @ 源、drop band + chip、codec 回源(含消息原文)、**确认卡(host 桥接 + 按 domain 卡片)**、查看上下文跳转 | ✅ 除 @ 三组排序与锚点高亮外齐备 | | **mention token 协议** `@yzj:{type}:{id}` | `yzj:{JSON}` 前缀编码(kind 含 message/group/doc 等) | 🟡 与设计格式不同但功能等价;**消息 ref 已携带 groupId**(回源能力达成,设计 §5.4 硬性要求满足) | ## 2. 工具清单对照(§5.1)— ✅ 全量对齐 - 设计清单 17 项全部有实现对应(`yzj_group_list`→`yzj_im_group_recent` 等,§5.1 主表已列实现名映射列)。 - 补充工具 14 项全部实现(§5.1 表后)。 - **门禁**:设计清单全部写工具 + 补充表写工具**均已入闸**(`guard.ts` 22 项:5 强确认 + 17 标准确认),只读全放行;`yzj_file_download` 仅 `overwrite` 时确认。风险分级(standard/strong)随 `yzj/ask-pending` 事件传给确认卡(强确认红色卡片)。 - 未登录引导:工作台会话列 + 设置→云之家 登录卡(`/yzj auth-status` / `auth-login` 拉起本机 `yzj-cli auth login`);`failureDigest` 检测 auth/登录类 stderr 后仍附同一条命令兜底。 ## 2A. 设计补强|悬浮窗全量可拖拽 → composer(用户思路)— 🟢 已达成 六类条目(知识库/文档/多维表格/日程/会话/消息/联系人)全部可拖、全部有 chip、codec 提交时回源注入: | 设计硬性要求(v1.6 §5.2) | 实现 | 状态 | |---|---|---| | 1. 消息 ref 必须携带 `groupId`,回源原文 | ✅ 拖拽载荷带 `group`,serialize 按 `(groupId, msgId)` 回源;锚点缺失降级「快照(原文可能已变)」 | ✅ | | 2. dbt 节点附 `sheet get` 表结构摘要 | ✅ `context.ts` doc 分支对 `fileSuffix=dbt` 追加表结构预览(新增 `/yzj sheet-get` RPC 端点) | ✅ | | 3. doc 摘要显式深度提示 | ✅ 摘要尾部注明「完整内容可用 `yzj_doc_block_list` / `yzj_doc_get` 获取」 | ✅ | | 4. 拖入即处理引导(P2 可选) | ✅ drop 后快捷动作行:让 agent 总结 / 起草回复 / 沉淀知识库(一键插入指令文本) | ✅ | ## 3. mention token 协议(§5.4)— 🟡 功能等价 | 维度 | 设计 | 实现 | 状态 | |---|---|---|---| | 格式 | `@yzj:{type}:{id}` | `yzj:{json}` | 🟡 不互认(下期扩展需别名映射),功能等价 | | 消息指针 | `{groupId}:{msgId}` | `yzj:{json}` 内 `id`=msgId + `group`=groupId | ✅ 回源能力满足设计硬性要求 | | 懒解析 | 序列化时刻 | ✅ | ✅ | | 失败降级 | 明确提示 | ✅ 快照标注 | ✅ | | 出处记录 | Trajectory 结构化事件 | 🟡 序列化文本落日志;无独立引用事件(外部插件事件受限,见 §4 注) | 🟡 | ## 4. 确认流 / 确认卡(§5.2、旅程 7)— 🟢 已落地(含一处受限降级) **实现形态**:`tools/pre-execute` ask(guard,含分级)→ `yzj/ask-pending` 广播参数 → host `write-gate` 应答 `approval/request` waterfall(yzj_* 加上绑定家园的 `robot_notify` / `robot_continue`,配对 `approval/asked` 审计 id,内存 pending 记录)→ 浏览器确认卡(`tool.call.toolview` keyed)查询/决策(RPC `write-list`/`write-decide`)→ 终态由官方 `tools/result` 驱动。 | 设计点 | 实现 | 状态 | |---|---|---| | 风险分级(标准/强确认) | ✅ guard 两级 + 卡片红色强确认徽标 | ✅ | | 全部写工具入闸 | ✅ yzj 写族 + `robot_share_write`;绑定家园另加 `robot_notify` / `robot_continue`(D9) | ✅ | | 按 domain 分发渲染 | ✅ im/doc/kb/sheet/calendar/file 六种参数详情 | ✅ | | 按钮:确认 / 取消 / 查看上下文 / 编辑 | ✅ 全四按钮(编辑=草稿塞回 composer + 取消请求) | ✅ | | 查看上下文跳转 | ✅ 打开面板并切 tab(im→会话群、doc/kb/sheet→知识库、其余→日程) | ✅ | | 刷新可回放 | 🟡 pending/approved 由 host 内存表恢复(SPA 刷新存活);终态由官方 tool/call+tool/result 事件回放;host 重启降级普通卡 | 🟡 满足主体 | | `yzj.write/request\|resolved` 事件族 | ❌ **受限降级**:harness 对外部插件的自定义 session 事件类型无注册面(`KNOWN_SESSION_EVENT_TYPES` 生成白名单 + `Session.append` 无 `ignorable` 入口),故确认卡状态不进会话日志,改由 host 内存 pending + 官方工具事件承载 | ⚪ 机制边界,文档备案 | | 标准确认同会话同目标合并 | ⚪ 未实现(设计标注「待评审拍板」) | ⚪ 待拍板 | | 终态 deep link | ✅ doc 类结果卡带「打开文档」链接;消息类跳面板锚点 | 🟡 消息类锚点定位待补 | ## 5. yzjReader 服务(§5.1)— 🟡 以 RPC 通道替代 `/yzj` Connection RPC channel(`workspaces/docs/events/groups/messages/whoami/search/doc-get/doc-blocks/sheet-get/workspace-get/event-get/contact-get/write-list/write-decide`)覆盖面板查询 + 引用回源 + 确认卡决策;client 内存 Map 缓存引用上下文。缺 append-only 持久缓存与撤回检测(P2 可选)。 ## 6. 悬浮窗(§5.2、旅程 1)— 🟢 达成 四 tab(知识库/日程/会话/我的)、双向分页、手动刷新、全条目可拖、CLI unreadCount 徽标、**角标轮询**(展开 30s / 收起 5min,汇总 unreadTotal 徽标)。 ## 7. @ 候选源与 codec(§5.2、旅程 5)— 🟡 | 设计点 | 实现 | 状态 | |---|---|---| | InputTriggerSource | ✅ 三组:云之家·同事(order 0)/ 云之家·会话(order 1)/ 云之家·文档(order 2),另保留 codec 载体源 | ✅ | | 三组候选(同事 order=0 / 群 order=1 / 文档 order=2) | ✅ 按设计分组与排序;文档组 warm 前 3 个知识库首层 | ✅ | | @同事 越权边界 UI 明示 | ✅ 候选描述注明「仅你有权查看的范围」 | ✅ | | @同事 起草消息给他 | ❌(选中即引用注入;起草走确认卡流程,无独立入口) | ⚪ 可选 | | ReferenceCodec 回源 | ✅(含消息原文、dbt 表结构) | ✅ | | 多 chip 合并序列化 | ❌ 受限:dsh chip 管道逐 chip 序列化(§15 备案) | 🔒 | | chip 源失效变灰 | ❌(快照标注已提供,灰 chip 未做) | ⚪ 可选 | ## 8. 三层通知(§5.3)— 🟢 层一/三已落地,层二以 skill 引导落地 | 层 | 设计 | 实现 | 状态 | |---|---|---|---| | 1 悬浮窗角标 | `lastSeenMsgId` diff 轮询 | ✅ 轮询 unreadCount 汇总徽标(CLI 已带未读数;未做逐群 lastSeen diff) | ✅ 主体 | | 2 schedule 筛选播报 | `every` 提醒 → agent 拉增量筛选 → 通知卡 | 🟡 schedule_create 为 harness 内置工具(已核验存在);skill 交付「创建提醒 → 拉增量 → 筛选 → 播报」流程引导;**通知卡按钮受限**(外部插件事件限制,播报为普通会话文本 + 面板自查) | 🟡 | | 3 浏览器系统通知 | 自接 Notification | ✅ unread 增量触发、点击聚焦 + 打开面板、首次点击授权 | ✅ | ## 9. 面板跳转服务 yzjPanel(§5.2)— ✅ 达成 确认卡「查看上下文」打开面板 + 切 tab + 加载群消息/workspace 文档;**锚点定位高亮**:im 回复类写操作锚定 `replyMsgId`,消息列表滚动定位并高亮(`itemAnchored`)。 ## 10. dsh skill(§5.1)— ✅ 已交付 `packages/bundle/skills/yzj-cli/SKILL.md`(bundle files 打包):红线(禁止编造 ID、写前先查、不得主动群发)+ 工具优先 + 四种 mention 引导 + schedule 播报流程 + 影子任务库表结构与规则 + 常见问题。安装方式:复制到 `~/.agents/skills/yzj-cli/`。 ## 11. 影子任务库(§5.1 顺带)— ✅ 已交付 skill「影子任务库」章节含完整表结构(`todo_id`/标题/`状态` 状态机/负责人/DDL/来源消息/推进日志)与使用规则(创建/推进/查逾期全走确认卡)。 ## 12. 安全与异常分支(§5.5、旅程 8)— ✅ 主体 单点门禁 ✅、身份/凭据 ✅、审计 ✅(批准对 + 工具事件落日志)、完整参数展示 ✅(卡片全文不截断)、未登录引导 ✅(工作台/设置登录卡 + 工具摘要兜底)、ID 失效不编造 ✅、确认卡无人处理挂起 ✅。快照决策标注 ⚪ 待拍板。 ## 13. 旅程与阶段验收对照(§4、§6) | 旅程 | 状态 | |---|---| | 1 悬浮窗看消息 | ✅(含角标轮询) | | 2 三层通知 | 🟡(层一/三 ✅;层二为 skill 引导 + 面板自查,通知卡按钮受限) | | 3 拖→起草→确认卡→发送 | ✅ 全闭环(含消息原文回源、确认卡、查看上下文跳转、真实 E2E) | | 4 讨论沉淀知识库 | ✅(确认卡 + doc 链接;落位预览=知识库 tab 跳转) | | 5 @ 拉上下文 | ✅(三组:同事/会话/文档,真实候选;「起草消息给他」⚪ 可选) | | 6 知识库问答 | ✅ | | 7 确认卡状态机 | ✅(待确认→已批准执行中→工具结果终态;取消;真实 E2E) | | 8 异常分支 | ✅ 主体(未登录登录卡 + 工具摘要/ID 不编造/挂起不写;灰 chip ⚪ 可选) | | 阶段 | 完成度 | |---|---| | P0 环境验证 | ✅ | | P1 yzj-tools(工具/门禁/确认卡桥接/skill/影子库) | ✅ ~98%(剩余仅 ⚪ 可选与受限项) | | P2 yzj-ui(悬浮窗/@ 三组/chip/codec/确认卡/跳转/通知) | ✅ ~98%(剩余仅 ⚪ 可选与受限项) | ## 14. 工程侧状态 - link 依赖相对化 ✅,本机(Windows)可 install/build/test(67 passed + 2 平台跳过);bridge 增加 Windows npm 全局 CLI 启动器解析(真实 CLI 链路打通,8 项真实冒烟执行)。 - harness 机制核验:`shell.overlay`、`ConversationNodeDefinition`、`inputTriggers`、`approval/request` waterfall、`schedule_create`、`tools/result` 均存在;**外部插件自定义 session 事件类型不可用**(确认卡事件族降级的原因,§4 注)。 - 文档同步:README 已更新(确认卡/改造版 skill 红线/相对依赖/受限说明),skill 已装入 `~/.agents/skills/yzj-cli/`(原版备份 `SKILL.md.orig`)。 --- ## 15. 验收结论与残余项(v1.6 基准) ### ✅ 全部可开发缺口已完成 P0 消息回源、P1 门禁分级/确认卡(含真实 E2E)/通知层一三/skill/影子库/锚点定位高亮、P2 @ 三组/dbt 预览/摘要提示/拖入即处理引导/未登录引导/越权明示——均落地并有测试(67 passed,2 Windows 平台跳过)。**旁路已封堵**:改造版 skill 红线生效,模型写操作必须走工具确认卡(真实 E2E 复现并验证)。 ### 🔒 机制受限项(harness 契约边界,文档备案) 1. `yzj.write/request|resolved` 持久化事件族(`KNOWN_SESSION_EVENT_TYPES` 白名单),由 host 内存 pending + 官方工具事件承载,主体语义达成。 2. 通知卡(ConversationNodeDefinition 按钮卡)同因受限;第二层播报为 agent 文本 + 面板自查。 3. 多 chip 合并序列化:dsh chip 管道为逐 chip codec 契约,无批量序列化面;多条引用按 chip 位置注入(行为等价,缺时间排序合并的展示层整理)。 ### ⚪ 待拍板 / 可选(设计标注归属,未实现) 4. 标准确认同会话同目标合并。 5. 拖入 chip 快照留存决策标注。 6. @同事 选中后「起草消息给他」独立入口。 7. chip 源失效灰化(当前为快照标注降级)。 ### 验证证据 - `pnpm -r --sort build` / `typecheck`:4 包全绿。 - `pnpm test`:67 passed + 2 skipped(Windows 平台限制),**含 tool-yzj 8 项真实 CLI 冒烟**(登录态下执行 whoami/知识库/通讯录/最近会话/日程)。 - **确认卡真实端到端**(`.acceptance/verify-confirm-e2e2.mjs`,真实登录态 + 真实 agent + 用户授权的目标群「830 项目【登顶计划】」):**7/7 PASS**——模型调 `yzj_im_message_send` → 门禁 ask → 确认卡渲染(目标群 ID / 全文 / 确认 / 取消 / 查看上下文)→ 点击确认 → 工具真实发送 → 卡片结算;`im message list` 独立回查确认消息入群。**过程中发现并封堵一个旁路**:官方原版 skill 引导模型走 bash 直调 CLI(绕过确认卡)——改造版 skill 已装入 `~/.agents/skills/yzj-cli/`(原版备份 `SKILL.md.orig`,references 保留),红线「写操作必须走 yzj_* 工具」生效后确认卡链路正常。 - **真实浏览器验收**(`.acceptance/verify-real-data.mjs`,已登录 yzj-cli + 独立 dsh web 实例 + 系统 Chrome):**8/8 PASS**——知识库真实列表、日程真实事件、20 个真实群组、群消息加载、@ 菜单会话/文档组真实候选、同事组关键词检索(带可见范围提示)、零页面错误。 - **无 CLI 降级验收**(`.acceptance/verify-windows.mjs`):9/9 PASS——插件挂载、面板四 tab、优雅错误横幅(无 500)、@ 菜单不崩溃。验收中抓到并修复 4 个真实 bug(toolview 同 key 注册冲突、store 跨 scope 冲突、bridge spawn 500、dsh.client.inject 配置)+ Windows npm 启动器解析(bridge 真实 CLI 链路)与 @ 候选 warm 时序问题。 - 客户端 bundle 重建成功(`lib/client.js`)。 *本文档为对照记录,不替代 v1.7 设计原文;标注「待拍板」的项目维持原设计的决策归属。**v1.8**:写路径两分已拍板([`dsh-home-session.md`](../spec/dsh-home-session.md) D9);会话家园目标 vs 三面现状见 §22。* --- ## 17. v1.5 增补|待办功能落地(2026-08-15,用户授权自主决策后开工) §11.2 待拍板项全部拍板(结论见 `../spec/todo-design.md` §11.2),随后完成开发: | 项 | 实现 | 状态 | |---|---|---| | T0 record digest 丢字段值 | `sheet.ts` `fieldsOf` 兼容 `fields` JSON 字符串形态(create/update/list 全路径) | ✅ 含回归测试 | | T1 todo 工具族 | `todo.ts`:`yzj_todo_list/create/update/complete` + `ctx.yzjTodo` 服务(state/ensure/create/toggle);稳定 ID 幂等、host 状态机、追加日志、自动发现/开通任务库(`todo` 配置可显式绑定团队库);guard +3(25 写工具) | ✅ 14 项单测(fake bridge) | | tag 核心理念 | `#tag` tokens 存储 + host 归一化;`yzj_todo_list(tag)` 聚合 + 面板标签轨 chips 过滤 + chip 回源携带 tags | ✅ | | T2 面板待办 tab | 分桶(逾期/今天/进行中/待办/已完成)+ 标签聚合 + 快捷新建(`#tag`/日期片段解析)+ 一键开通 hero + 勾选完成/重开(乐观更新)+ 整行拖 chip;`todo-state/ensure/create/toggle` RPC;确认卡 `todo` 域(状态/负责人/DDL/标签/refs);工具卡 todo 族(45 keyed);codec `kind:'todo'` 回源 | ✅ 8 项组件测试 | | demo 阶段声明与迁移 | `../migration/todo-backend-migration.md`:四层架构(工具/核心/服务/浏览器 不变 ↔ 存储适配层可换)、字段映射、8 条实测格式事实、迁移五步、API 需求清单 | ✅ | | T3 闭环(逾期播报/催办实测) | 链路已通(schedule + `yzj_todo_list overdue` + 催办消息走确认卡);真实使用走查待续 | ⏳ | **第二轮验收证据(2026-08-15,隔离实例 :3091,3080 全程未动)**: - **浏览器旅程 14/14 PASS**(`verify-todo-browser.mjs`):悬浮球 → 四 tab → 待办 tab 真实库加载(非开通 hero)→ 快捷新建(`#tag`+日期片段解析预览「将创建」)→ 创建落库 → 标签轨过滤 → 勾选完成 → 拖拽行就绪 → demo 声明与任务库链接 → 零页面错误。 - **视觉健全性 6/6 PASS**(`verify-todo-style.mjs`,DOM 计算样式):快捷创建圆角卡片、品牌蓝添加按钮、分桶标题、圆形状态点、grab 拖拽光标、四 tab 布局——CSS Modules 真实生效。 - **确认卡 agent E2E 12/12 PASS**(`verify-todo-confirm-e2e.mjs`,真实 agent + 真实放行):`yzj_todo_create` → approval/asked → 确认卡(新建待办/标题/#e2e 标签/四动词)→ 点击确认 → approval/decided → 工具真实落库(含标签与推进日志)→ 动态发现任务库交叉验证 → 探针清理 → 零页面错误。 - **第二轮修复的真 bug**:库发现只扫第一个个人知识库(CLI 首项是 AI速记知识库而非我的知识),导致重复开通第二个任务库——已改为扫描全部个人知识库(≤8)再决定开通(`todo.ts` resolveLibrary,新增多库扫描单测)。会话日志诊断还证实第一轮 E2E 实际成功(approval/decided → created T-…-005),首报 FAIL 为脚本自身硬编码旧库 ID 与结算检测缺陷,均已修复。 ## 18. v1.6 增补|现有功能 UX 打磨(2026-08-15 第三轮) 审计知识库/日程/会话三 tab 与全局交互后修复三处摩擦(会话 tab 审计结论:已完备,未动): | 摩擦点 | 修复 | 验收 | |---|---|---| | 日程打开是空右栏(要求先点日期);持久化的旧选择/旧月份会残留;日标题渲染成「00:00」 | 打开日程 tab **始终落在今天**(当月+当日+清旧选择);月导航回到当月自动选今天;新增「今天」快捷按钮;日标题改人话(`今天 · 周六` / `8月20日 · 周四`) | 浏览器 5 项 PASS | | 知识库只能看第一层文档——有子文档的库(如 127 篇的安全体系库)无法下钻 | **文件夹下钻**:有子项的节点显示 `›` 钻入按钮 + 子项数;面包屑(知识库 / 文件夹…)可逐级回跳;行点击仍开预览,拖拽语义不变 | 真实库钻入/回跳 3 项 PASS | | Esc 只关 lightbox,不关面板 | **Esc 逐层收起**:表情面板 → 回复条 → 面板本体 | PASS | 浏览器验收 `verify-ux-polish.mjs` **11/11 PASS**(隔离实例 :3091,真实登录态,含「切走再切回日程仍落今天」回归项);全量测试 93 passed。 ## 19. v1.7 增补|团队协作待办库(2026-08-15 第四轮) v1.6 §11.2 决策 1「双轨库」完整落地: | 能力 | 实现 | 验收 | |---|---|---| | 任务库切换器 | 待办 tab 顶部 pill:📋 个人 / 👥 团队 + 知识库名(当前激活库身份由 state() 经 doc-get + 5min 缓存的 workspace 索引廉价带出,不阻塞首屏);点开列出发现的全部「待办任务库」(个人+企业扫描 ≤12+12,5min 缓存),active 项打勾 | 浏览器 PASS | | 团队库开通 | 「新建 / 选择团队任务库…」二级菜单列出企业知识库(permissionLevel 排序,>2 只读禁选并提示);选定后 adopt-or-provision(已有同名库则复用,缺任务表则补建,全无则新建 dbt+任务表)并自动激活 | 真实企业库「六大场景内测」开通 PASS | | agent 跟随激活库 | 切换写入 host `TodoBindingHolder.override`,工具族与 RPC 同源共享——面板建的库 agent 写的库永远是同一个;失效库(被删)override 自动清除回落个人发现 | 单测:override 路由写入团队表 + 失效回落 | | 持久化 | 浏览器 localStorage 记住选择,面板重开自动重放 todo-select;headless 用 `todo` 配置钉默认库 | 浏览器重开恢复 PASS | | 团队语义 | 分派=assignee(姓名→openId 解析);催办=IM 给负责人(确认卡);多人共用 last-write-wins + 推进日志可追溯 | 既有能力组合 | 浏览器验收 `verify-todo-team.mjs` **15/15 PASS**(真实企业库开通 → 面板建待办真实落入团队库(含 #团队 tag,CLI 交叉验证)→ 切回个人库恢复 → 探针清理,零页面错误);全量测试 97 passed。RPC 端点 22→25(`todo-libraries`/`todo-select`/`todo-ensure-team`)。 实测探针副产物(进迁移文档 §3):`--records` 必须数组;`fields` 恒为 JSON 字符串;SingleSelect 需 `data.items` 预注册;MultipleSelect 动态值静默丢弃;Contact 写入 500;`sheet create` 带 `openWebUrl`;新 dbt 自带空默认表。工具数 41→45,写门禁 22→25,RPC 端点 18→22,面板回归四 tab(第四 tab=待办)。 --- ## 16. v1.4 增补|UI 后续演化对照(git `08fc7b1` → `af3bf5d`,19 commit,~4300 行) 验收收口(v1.3,`de3c058`/`08fc7b1`)后,ui-yzj 经 19 个 commit 继续演化,host 侧(tool-yzj/bridge/bundle/skill)除三处小改(Windows 启动器、`im send` 增 `refs` 参数、skill 同步一行)外零变动。逐项对照: | # | v1.3 收口时状态 | 现状(`af3bf5d`) | 性质 | |---|---|---|---| | 1 | 面板四 tab(知识库/日程/会话/我的) | **三 tab**:「我的」删除(`5112849`);身份经 `yzj_whoami`,找人经 @ 候选 | ⚪ 偏离设计 §5.2,待拍板(恢复 vs 修订设计) | | 2 | 侧边栏底部按钮入口 | **悬浮球唯一入口**:hover 快捷坞、持久化显隐(`9f970b7`→`af3bf5d`) | 🟢 演进,设计 v1.7 已修订 | | 3 | 面板只读浏览 | **面板真 IM composer**(文本/图片/文件/回复/表情,`d60ece0`/`3dc66e8`),经 `/yzj im-send` 直发,不经确认卡 | ⚪ 当时引入「用户直写」路径(原则待拍板);**v1.8 D9 已成文**,composer 作为家园则否(§22 G6) | | 4 | 拖入即处理快捷动作(§2A 第 4 行 ✅) | **已移除**(`2a3a556`),改为全屏 drop overlay 直接成 chip | ⚪ 设计硬性要求 4(P2 可选)实现后删除,终局与否待拍板 | | 5 | 确认卡展示原始 ID | **去 ID 化**:ID 解析为群名/人名,原型风格(`bfb81c0`/`1d6ee38`);`refs` 关联引用 chips | 🟢 演进(同名目标可辨识性见待拍板 #8) | | 6 | lastSeen diff 角标 | CLI `unreadCount` + 本地已读持久化(`0dedff8`/`361788b`),刷新不回退 99+,「全部已读」 | 🟢 演进 | | 7 | 会话 tab 消息气泡 | 完整 IM:正序阅读、媒体/文件预览、表情、回复、日期分割线、锚点 tag、双栏布局、文档内容预览(`20cc7ba`→`7eb1b6c`) | 🟢 演进 | | 8 | RPC 15 端点 | **18 端点**:新增 `im-send`/`file-upload`(用户直写)与 `file-data`(媒体代理) | 🟢 演进(#3 的载体) | **维持不变**:41 工具、22 写门禁、@ 三组、codec 回源(含消息原文/dbt 表结构)、三层通知、确认卡四动词与锚点跳转、toolview keyed 注册。 ### 16.1 新增待拍板项(并入 §15 清单) 8. **「我的」tab**:恢复(通讯录浏览回归面板)vs 维持删除(@ 候选已覆盖找人)+ 修订设计 §5.2。 9. **用户直写原则**:**v1.8 已拍板**([`dsh-home-session.md`](../spec/dsh-home-session.md) D9/§8)——确认卡只门控 agent 写;用户从 DSH 发出(及现行面板 composer / 待办勾选/新建)即用户意志、不经确认卡。**尚未落地的是家园迁移**:用户发群应发生在绑定 DSH 会话;面板 composer 目标为移除/降级(§22 G6)。 10. **拖入即处理引导终局**:确认移除(修订 v1.6 硬性要求 4)或恢复。 11. **确认卡同名目标可辨识性**:去 ID 化后两个同名群/同名人在卡上不可区分;可考虑主显名称 + 可展开 ID 明文(安全审计可回溯)。 ### 16.2 实测新发现(2026-08-15,真实库探针) - **`yzj_sheet_record_list` 丢字段值**:CLI list 输出 `records[].fields` 为 JSON 字符串,`recordLine` 解析吃成空对象,digest 只剩 record id(UI `clipJson` 同样只当文本);此前冒烟未覆盖 sheet 记录故未暴露。修复列入待办 T0(见 `../spec/todo-design.md` §11.1)。 - Date 字段真实值形态为 `YYYY/MM/DD` 字符串;Contact 字段无真实实例可考,写入格式待探针(待办设计 §3/§11.3)。 --- ## 20. 机器人通道 R1(host 面,2026-08-16) 设计基线:`../spec/robot-channel-plan.md` §3.2/§3.6(DM 子集)。新增包 `packages/robot-yzj`(`ctx.yzjRobot`),bundle 第 5 行挂载。 | 设计项 | 实现状态 | 证据 | |---|---|---| | WS 入站(spike ①③⑦a 协议) | ✅ `protocol.ts` 帧分类 + `socket.ts` 心跳/陈旧/退避重连 | `tests/protocol.spec.ts`(11)、`tests/socket.spec.ts`(6,含停止清定时器) | | 出站 sendMsgUrl(§2.3 语义) | ✅ `outbound.ts` 信封/引用卡/notify/分片/限流/msgId 提取 | `tests/outbound.spec.ts`(9) | | S1 DM 持久 session + replyRootMsgId 锚定素材 | ✅ `router.ts`(session id `yzj-robot--`;`outboundAnchor` 记录出站 msgId) | `tests/router.spec.ts`(7) | | S2 ack-then-push + seq 水位防重发 | ✅ ack 即时引用回复;`whenIdle()` 后按 `assistant/message` seq 水位推回 | `router.spec.ts`(watermark 两用例) | | S3 命令族子集 `!help/!status/!mute/!unmute/!restart` | ✅ 独立成句才生效;restart dispose 旧 session | `router.spec.ts`(help/mute 两用例) | | S5/S8 触发与安全 | ✅ allowFrom 默认 CLI 登录用户(经 bridge `contact user get`);非白名单拒绝且不建 session | `router.spec.ts`(拒绝用例) | | 生命周期无残留 | ✅ `ctx.effect` → stop → socket 停 + router dispose | `socket.spec.ts`(stop 清定时器) | 已知缺口(转 §7.3 / R2):msgChg `needAck` 的 ack 帧未实现(服务端 ~90s 重推,仅噪音);面板设置卡与 `/yzj` robot 端点未做(R1 UI 半);群场景全未做。 验收口径(真实通道,待 GUI 集成后走):在「个人助手」DM 发非命令消息 → 3s 内 ack(引用原消息)→ agent 轮次收敛 → 回答以机器人身份引用推回;`!mute` 后静默、直接再发解除;非白名单账号拒绝。 ### 20.1 E2E 收口(2026-08-16 10:25,真实通道全绿) web profile 已装 `@dsh-yzj/robot-yzj`(link),`~/.dsh/profiles/web/cordis.patch.yml` 持 sendMsgUrl(凭据不入库)。隔离验证实例(端口 3093)跑通完整旅程: ``` 用户 DM「你好5(全链路最终验证)」(10:25:56) → 秒回「收到,处理中…」(引用原消息) → agent 轮次真实执行(opencode-go/deepseek-v4-flash,测试期临时配置;agent 还自主调了 yzj_whoami 核身份) → 10:26 完整回答以机器人身份引用推回 DM ``` 修复链(各配 pitfall):loader inject 声明(pitfall-005)→ resume-before-create + `meta.cwd`(pitfall-006)。34 单测全绿。**测试期 provider/model 配置已撤**(回 harness 默认路由),正式模型路由待拍板。残留:`_no-cwd` 下旧坏 session 已删;3093 验证实例供群机器人接入复用。 ### 20.2 R2 群场景收口(2026-08-16 10:37,金蝶最小DSH交流群实测) - **多机器人架构**:`robots[]` 配置数组,每通道独立 WS/sender/router(commit `b1c8104`);本机双通道并挂(个人助手 BOT-69ccc7 + 群机器人 BOT-6a80d097 = DSH-YZJ-TEST)。 - **群锚定实测**(对齐 §3.6 S1):顶层 `@DSH-YZJ-TEST 你好` → 秒回 ack(引用+定向 @提问者)→ 完整回答 BOT 身份推回;**引用机器人回答**追问「群里都在说啥」→ 同一 session 续接(agent 多工具轮次、自我纠错、跨 5 群摘要报告);`replyRootMsgId` 链根锚定生效,ack 本身也入锚(回复 ack 同样续接)。 - **免公网坐实**:隧道早已杀掉,群消息纯 WS 入站——spike ① 群场景收口。 - 35 单测全绿;测试期 provider/model(opencode-go/deepseek-v4-flash)标注于 profile patch 注释,正式路由待拍板。 - 待办(R2 余项):`!fork`/`!routines`、群内建议卡协议、msgChg ack。 ### 20.3 按会话模型覆盖(2026-08-16,UI 落地,`0a424fb`) - **架构**:`OverrideStore`(storage-domain `robot_yzj_overrides`,json backend 落 `~/.dsh/storages`)——键 `g:` / `dm::`;解析序**会话覆盖 > 通道默认 > harness 默认**,在 agent 创建时应用(已存在会话 `!restart` 后采用)。 - **面**:`/yzj` RPC 5 个 robot 端点(status/overrides/set/delete/models);面板第五个「机器人」tab(dock+TABS)——通道状态灯、覆盖编辑器(群选择器显示群名、provider/model 下拉来自 live 目录)、覆盖列表(变更后主动重拉)。 - **验收**:`verify-robot-pane.mjs` **10/10 PASS**(含 保存→切 tab 重载→持久化→删除 全环);截图 `.acceptance/shots-robot/`(gitignored)。 - **决策留档**:provider 目录合并 `listProviders()`(已激活路由)与 `listConfigurableProviders()`(休眠可选)——UI 可选全部 harness provider;未激活 provider 的模型列表可能为空(选择后由 agent 轮次按需暴露错误)。**决策反转(用户否决,2026-08-16)**:目录只列 `listProviders()`(已激活)——未配置的 provider 出现在选择器里是噪音;配置文件(channelsFile / patch)仍可引用未激活 provider。 ### 20.4 通道默认模型可配置(2026-08-16,`50bc120`) - **Config 新增 `defaultProvider` / `defaultModel`**:填进所有未自带 provider/model 的机器人——一行 profile 路由整个机群。**解析序定为四级**:会话覆盖(UI)> 机器人自带 > 插件默认 > harness 默认。 - **本机落位**:`opencode-go / deepseek-v4-flash` 为通道默认(用户拍板:默认便宜模型,强模型按群在面板覆盖);之前手配的逐群 flash 覆盖已删(冗余)。 - **验证**:`verify-flash-default.mjs` PASS(双通道行显示 flash 默认);真实 @ 往返(11:04,ack→flash 轮次→引用回推)确认默认路由驱动 agent。 ### 20.5 R2 全量收口(2026-08-16,`8b97c3b`) - **msgChg ack**:socket 对 `needAck:true` 的推送立即回 `{"cmd":"ack","seq":N}`——消掉实测的 ~90s 服务端重推。 - **群内建议卡协议(S8)**:`ConfirmBroker` 接管 `yzj-robot-*` 会话的 approval waterfall(GUI write-gate 让位)——写工具在机器人会话里触发时,推送编号卡(🔒 标准 / 🔴 强确认 + 参数摘要 + 30 分钟窗口),群内回复「`@机器人 确认 N / 取消 N`」裁决(**群面协议只送 @ 消息,确认必须带 @**——文档化);超时自动取消;跨会话不串卡。**实测全链**:doc_create 卡[1] → @确认 1 → ✅放行 → block_insert 卡[2] → @确认 2 → ✅放行 → 文档真实落《我的知识》+ deep link 回推(11:15–11:21)。 - **`!routines`**:fold 会话 `schedule/change` 日志列活跃提醒(dsh-schedule 纯函数 fold,无运行时依赖);`!help` 同步确认流程说明。 - 已知边界(留档):确认卡为进程内存态,host 重启即失效(对齐 GUI 确认卡的降级语义);R2 设计清单仅剩 `!fork`(跨群交接)未做,价值待群使用密度评估。 - 43 单测全绿(新增 confirm 6 + msgChg ack 2)。 ### 20.6 卡片能力面二轮实测(2026-08-16,修正初判) - **webhook 通道交互卡片判死**:8 个信封变体(msgtype 2/25/26 × param 三种挂法)全回落 `param:null` 纯文本——服务端白名单只放行 reply/notify 结构。初判"假模板渲染真卡片"系误读(应用类消息的富文本观感)。 - **应用类(msgType:1)确认为 webhook 唯一视觉卡片**:标题/主次内容/`webpageUrl` 跳转;与引用锚互斥(param 争用,实测 D/E 两变体)。**确认卡已用此形态上线**(`RobotSender.sendCard`,群内实测卡片标题/工具/确认提示三层结构 + ✅ 卡片回执)。 - **真交互卡片 = Adaptive Cards 1.4,开放平台通道**:重保群(698439d1e4b0d221d736ee42)告警平台卡片只读样本——`param.interactiveCard.cardJson` 内联完整 Adaptive 协议(Action.Submit 按钮/Input.Text/ChoiceSet/`_secondConfirm` 二次确认),回传走卡片平台→模板回调地址。R3 上 Adaptive 确认卡的协议依据已锁定,等 D 层协调。 - 设计文档 §4.1 spike⑥/§1.7 C 层/§3.5 R3 三处同步修正。 ### 20.7 R2.5:Claude Tag 对齐收口(2026-08-16,`0bb88e3`) - **PushHub(事件驱动推送)**:router 只排队轮次(ack 后即返回),**全部推送**由 `session/event` firehose + `agent/status`/`agent/error` 驱动——**任何触发源**(交互/定时/看板)的产出都会推回会话(C11 投递缺口补上);水位防重发、长任务每 5 个工具步推里程碑(`⏳ 进行中…`)、错误以有界失败行呈现(C4 完整)。 - **群记忆(C9/S4)**:`robot_yzj_memory` 域——「记住 …」存(去重、上限 30)、「忘掉 …」删、`!memory` 列;存储行以 instructions 上下文注入每轮。实测:记住→查询→注入生效全通。 - **入群自我介绍(S7/C14)**:每群首个会话跑 intro 轮(读群历史+提建议任务),进程内去重。 - **任务署名 ack(C12)**:ack 带任务摘要(`收到,处理中…(帮我演示…)`)。 - **对齐终局**:14 项中 12 项 ✅ 等价或更强、1 项 ⚠️(C3 群内须带 @,协议限制已文档化)、1 项 ➖(C7 自静音显式放弃);`!fork` 仍留观察。51 单测绿。 - 遗留观察:取消确认卡后部分轮次无收尾推送(agent 收尾产出为空的情形),非阻塞,下轮观察。 ### 20.8 R2.6:DSH→机器人 双向控制 + 工作目录(2026-08-16,`df3ac60`) **双向打通(操作者从 DSH 内部驱动机器人通道)——🟢 已落地并经真实通道验证**(设计见 `docs/spec/robot-channel-plan.md` §8): - **`robot_status`**:通道连接/cwd/provider/model/allowFrom/已见会话表面(groupId+robotId+lastSessionId)/live session;实测列出 `cwd=D:\dev\deepseek-harness`(宿主进程 cwd,可配置键 `cwd`/`defaultCwd` 覆盖)。 - **`robot_notify`**:主动通知推送到通道会话;实测群内收到「双向打通验证(来自 DSH 内部控制台)」。 - **`robot_continue`**:以白名单操作者身份注入消息走完整入站管线(ack/鉴权/确认卡/记忆/intro/轮次/推送);实测注入后群内 ack + 机器人回答;synthetic 消息不带 reply 锚点(fake msgId 服务端不存在);跨重启续接靠持久表面域 `robot_yzj_surface`(`surface::` + `recent:`,注入了真实 robotId/groupId/lastSessionId 后实测续接旧会话)。 - **`robot_fork`**:把机器人会话 fork 成操作者侧根会话(completed-turn seed + cwd + parentSession 谱系);实测生成 `fork-yzj-robot-…` 会话且出现在 `session.list`(GUI 会话列表可打开继续)。 - 服务面 + `/yzj` RPC(`robot-notify`/`robot-continue`/`robot-fork`)+ client 注入面同步补齐;工具体拒绝 `yzj-robot-*` 会话调用(防机器人自驱)。 - 决策记录:工具不过确认门控(机器人是操作者自有通道,allowFrom 已限定),见 spec §8.2。 **定时任务主动通知(C11 定时推送)——🟢 已闭环(2026-08-16 R2.7,外部引擎 + 自研投递)**: - 结论:**单独插件路线**(`docs/spec/routines-delivery.md`)——定时引擎采用社区 **dsh-routines**(专用 `ops` daemon profile),云之家投递自研 `ctx.chatnode` (`robot-yzj/src/chatnode.ts`,提交 `640f205`)。 - 端到端实测通过(隔离 DSH_HOME):routine `every 1m` → 调度器 tick → headless 子进程独立会话 → digest → `ctx.chatnode.send` → 机器人推送到「金蝶最小DSH交流群」, 群里收到 `[completed] c11-yzj / 定时任务 chatnode 投递测试通过。`; run 记录 `deliveries: [{file, ok}, {chatnode, ok: true}]`。 - 旧方案(在机器人会话里挂 harness schedule 工具,pitfall-007 的 `unknown tool`) 已随 `df3ac60` 后的清理提交退役:移除 `attachScheduleTools`/schedule 运行时/ flush 屏障监听;`!routines` 空态文案指向 `dsh routines list`。 - 实测坑(web profile 缺 jobs 控制器会崩调度器 tick、routines-cli 抢命令行、 Windows 子进程 dshBin/runModule、patch insert 格式等)见 `routines-delivery.md` §5.1。 **生产形态定稿(2026-08-16 R2.8,`ops 不直连机器人`)——通信桥落地**: - 用户要求 ops 调度器不直连云之家、一切机器人通信走我们的插件;最终为 **HTTP 桥,两端都是 robot-yzj**(`robot-yzj/src/bridge.ts`,提交随本行): web profile 在 webServer 注册 exact 路由 `POST /yzj/chatnode` (`bridgeToken` opt-in,loopback-only + Bearer 口令),ops profile 以 `bridgeTarget` 进入 client 模式(无 WS/无凭据/只提供 `ctx.chatnode`)。 - 被否决备选:文件监听 runs 目录(用户判定太 low)、ops 侧 webhook 直连 机器人 API(违反不直连)。 - `inject` 从 `['yzjBridge','agents','tools']` 改为 `['agents','tools']` (bridge 可选化,client 模式无需 yzj-cli 桥);单测 `tests/bridge.spec.ts` 全路径覆盖(真实 loopback HTTP,181 绿)。 - 生产布局与验收口径见 `routines-delivery.md` §6;端到端验证在 web profile 重启(web patch 生效)后进行。 ### 20.9 群工作区三层模型 + 共享区工具(2026-08-16,设计随提交) **背景**:cwd 原为 per-channel(全机器人共享一个目录)——群 A/群 B/DM 文件互通,话题间静默覆盖(harness `write` 是覆盖语义,无保护),与 Claude Tag per-thread 沙箱隔离(C13)存在静默降级。用户拍板三层模型(设计见 `robot-channel-plan.md` §8.4): - **目录模型**:群话题 session cwd = `<通道cwd>/groups///`(私有工作区,结构性无冲突);DM 落通道根;群共享区 = `<通道cwd>/groups//shared/`(跨话题显式协作,等价 Claude Tag 的文件同步通道);记忆按群不变。 - **权限模型(session 权限不动)**:机器人会话保持 workspace-write;共享区在 session workspace 外,内置写工具被沙箱拒,`robot_share_write`(插件宿主直写)是唯一写通道;读共享区用内置 `read`/`glob`(只读不受沙箱限制,零新工具)。 - **工具面**:`robot_share_write`(默认存在即自动唯一名 `name-2.ext`、`overwrite:true` 才覆盖、临时文件 + rename 原子写、filename 防穿越)+ `robot_share_list`(名/大小/mtime);进 `WRITE_SPECS`(standard),机器人会话自动走群内建议卡;工具不禁机器人会话(区别于 §8.2 operator-only)。 - **注入**:每轮对群会话注入共享区指令(绝对路径 + 强制走 `robot_share_write`),DM 不注入。 - **验收**:单测覆盖群/DM cwd 解析、回复续接复用同目录、共享区指令只注入群会话、唯一名/覆盖/穿越拒绝;**沙箱行为实测(2026-08-16,3081 测试实例 + 假通道 overlay)**:内置 `write` 对 cwd 外非临时区路径被拒(`D:/dsh-share-outside/…`)、cwd 内放行;`robot_share_list` 无表面时正确报错(工具注册/接线/错误语义);`robot_share_write` 确认卡(「工作区写操作确认」+ 拒绝/允许一次)→ 允许 → 落盘 `/groups/probe-g1/shared/hello.md` → `robot_share_list` 回读可见,端到端全通。**边界条件(实测发现)**:workspace-write 豁免平台临时区(`%TEMP%`)——通道 `cwd` 配置在临时区下时共享区可被内置工具写,「唯一写通道」不成立;默认宿主 cwd 不受影响,部署注意(spec §8.4 已记录)。 ### 20.10 全量 Gap 盘点(2026-08-16 R2.8 后,设计 vs 实现) **结论:功能面 ~97% 闭环**;剩余真 gap = 群 watcher + 1 个外部依赖(Adaptive 卡片)+ 生产收口三步。 | 类别 | 项 | 状态 | |---|---|---| | 🔴 生产收口 | 生产 GUI 重启 → 桥路由 + 插件市场 UI + digest 进群(R2.8 验收最后一步) | ✅ **已闭环(2026-08-16 21:20/21:26 生产实测)**:桥 POST `{ok:true}`、定时 digest `[completed] c11-prod` 经 ops→桥→生产 GUI→群机器人推送,群内实收 | | 🔴 生产收口 | ops daemon 常驻化 | ✅ **`dsh web` 唯一入口**(R2.12:web patch `autoStartOps: true` → robot-yzj 经 `~/.dsh/ops-wrapper.mjs` 自动拉起,pid 文件幂等;手动启动脚本/登录自启已删除) | | 🔴 生产收口 | 生产 smoke(`.acceptance/verify-prod-smoke.mjs` 已提交) | 未在生产跑 | | 🟡 设计有代码无 | `!fork` 跨群交接(S3/C5;§20.5 标"仅剩") | ✅ 已实现(R2.10:目标群 surface + 本群最近会话上下文摘要 + continueFromDsh 全管线交接;顶层/链内均可触发;R2.11 目标支持**群名或 groupId**——群名经 CLI `im group recent` 惰性解析并持久化到 surface) | | 🟡 设计有代码无 | `!configure` / `!feedback`(S3 命令族表) | ✅ 已实现(R2.10:!configure 回 GUI 设置链接(config `guiUrl`);!feedback 落 `~/.dsh/robot-feedback.log` + 回执) | | 🟡 设计有代码无 | 会话 deep link(S2「在 DSH 中打开会话」) | ✅ 降级实现(R2.10:GUI 无会话 URL 路由,最终推送附 `📎 本任务完整记录:(DSH 会话 )`;config `guiUrl` 开关) | | 🟡 设计有代码无 | 群 watcher 关键词轮询(S6) | 未实现(schedule 已走 dsh-routines) | | 🟡 外部依赖 | Adaptive 确认卡 / checklist 原地更新(S2/R3) | 协议依据已锁定,等开放平台协调 | | ⚪ 可选 | 标准确认同会话合并 / chip 快照标注 / @同事起草入口 / chip 灰化 / 灰 chip | 设计标注可选,未实现 | | 🔒 受限 | yzj.write 持久化事件族 / 通知卡按钮 / 多 chip 批量序列化 / 自定义 session 事件 / 确认卡进程内存态 | harness/协议边界,已备案 | | 🧹 发布 | 对外 git 安装走根 `@dsh-yzj/bundle` registry 依赖;workspace 六包保留 `link:` 兄弟 checkout(开发事实源) | ✅ 关闭(2026-08-18 起;**2026-08-19 升 rc.7**):根 `dependencies` 已是 `^0.1.0-rc.7`,无 `link:`;tag `v0.1.0` / `v0.1.1` 已打。**不要**把 workspace `link:` 换成 registry——会拆掉 vitest alias / 类型闭环。browser half 须 `import type {} from '@deepseek-ai/dsh-client-ui-tool/client'` 才能 merge `tool.call.toolview`;session 槽 `inject` / overlay hanger 用 branded `SessionId`(pitfall-034)。口径见 `docs/release.md` | | 🧹 业务 | routine 内容为 demo 巡检,真实定时任务未定义 | 待用户提供 | **文档修正(同提交)**:`robot-channel-plan.md` §3.6.4 对齐表 C5 原标 ✅ 与 §20.5「!fork 未做」矛盾——已改标 ⚠️ 观察项;R2.10 `!fork` 落地后改回 ✅(含 !configure/!feedback/会话 deep link 降级实现)。 ### 20.11 机器人面板升级:通道 cwd + 群共享工作区(2026-08-16,随 UI 提交) - 机器人 tab 三个增量:① 通道状态行显示解析后 cwd(`robot_status` 数据本来就有,UI 补投影);② 新增「群共享工作区」section——**先选已注册的机器人通道,再选该通道真实见过的群表面**(`robot_status` surface,过滤 DM 的 BOT- 前缀;群名从会话 tab 群缓存解析,缺失显示 groupId)→ 拉 `robot-share-list` 显示共享区路径 + 文件列表(名/大小/mtime,空态);③ 面板直写表单(文件名 + 内容 → `robot-share-write`,携带所选通道 robotIndex),复用 `writeShareFile` 的自动唯一名语义,**面板直写 = 用户本人意志,不经确认卡**(对齐 im-send 直写语义;agent 会话写仍走确认卡)。多机器人下共享区按通道隔离(各通道 cwd 不同)。 - RPC 端点 +2(`robot-share-list` / `robot-share-write`),`/yzj` 共 36 端点;注入面 `robotShareList`/`robotShareWrite`。 - **演进(同会话内多轮)**:① 两级结构(机器人列表 → 详情);② 文件区并进群卡片(不再单独选群);③ **面板直写 UI 移除,改为「打开」预览**——`robot-share-read` 端点(只读、20k 字符截断、防穿越)+群卡片内预览(文件名 + 内容 + 关闭);机器人 agent 的 `robot_share_write` 工具不受影响;RPC `robot-share-write` 端点保留(向后兼容)。 - 验收:ui-yzj typecheck/build/bundle 通过、63 单测绿;浏览器走查待 web profile 重启后跑 `verify-robot-pane.mjs` 扩展(面板共享区浏览 + 直写落盘)。 ## 21. 记忆库组件 memory-yzj(2026-08-16,设计随提交) **背景**:用户提供 dream-vault 导出包作参考,要求对照 dsh 插件生态("dsh find")的记忆实现,做一个可接定时任务、后续可接群组记忆的记忆组件。调研结论(30+ 记忆插件,代表:dsh-mneme / dsh-native-memory / @max-null/dsh-memory)与全部取舍见 `spec/memory-vault-design.md`(D1-D11 决策表)。 **落地(首版,全部已实现)**: - 新包 `@dsh-yzj/memory-yzj`(`ctx.yzjMemory`):明文 Markdown vault,默认根 `$DSH_HOME/yzj-memory`,scope 分仓(`user/`、`group-/` 同构预留);sections(frontmatter `title/order/tags`)/ entities / observations(open/archived)+ log.md(追加审计)+ index.md(dream 重建)+ sections.yaml(仅 `inject_char_cap`,默认 6000)。 - 5 个工具:`memory_observe`(草稿区写入,去重 + 容量上限 200,唯一 agent 可写面)/ `memory_read` / `memory_search`(确定性关键词)/ `memory_dream_load`(全量状态 + 内容 rev)/ `memory_dream_apply`(决策 JSON 字符串入参——todo 工具族 records 同款范式;逐条校验,rev 不符或目标缺失仅拒该条;log/index 总是重建)。**不进 WRITE_SPECS**:本地草稿非云之家写(设计 §3/D4)。 - 注入:`ctx.get('systemPrompt')` 机会式注册 `yzj-memory` 动态 context,每次组装现算 `injectScopes` 投影(无陈旧镜像);空库零贡献。 - 定时对接:`spec/memory-dream-routine.yaml`(dsh-routines 真 schema:name/schedule/timezone/profile/cwd/overlap/timeoutMin/deliver/prompt),固化规则全在 prompt,工具只做机械应用;headless profile 需挂 memory-yzj 行。 - 群组留缝:`allowScopes` 白名单扩 `group:` 即激活(scope 正则 + 目录映射 + 仓间隔离已有单测);robot-yzj 接群注入/群内「记住」为后续工作(设计 §8)。 **与设计的实现级偏差(设计已同步)**:① sections.yaml 从「段顺序+cap 双职责」简化为仅 cap(段的 order/title 移入各段 frontmatter——一处事实一处存放);② 服务方法同步实现(注入 provider 契约是同步字符串;单进程串行,跨进程靠纯创建+原子 rename+rev 锁);③ dream_apply 的 decisions 为 JSON 字符串参数(工具框架的数组 of object 参数不支持,todo records 同款)。 **验收证据**:`pnpm vitest run packages/memory-yzj` 21 测试全绿(frontmatter 参考格式往返、observe 去重/容量/scope 隔离、投影排序与截断、检索命中行、五类决策 + rev 冲突保护人工编辑 + 畸形决策进报告、临时文件卫生);`pnpm run build`/`typecheck` 全仓通过。**待真实环境验收**(web profile 重启后):提示组装含 `yzj-memory` 上下文、会话内 observe → 手动 dream → 注入更新;headless routine 端到端(ops→桥→群摘要)复用 routines-delivery §5 链路。 ### 21.1 记忆面板(2026-08-16 v0.1 增补,设计 §「v0.1 增补」随提交) 用户要求 UI 可看记忆。原「浏览器管理面板」非目标提前转正: - **ui-yzj**:工作台第六 tab「记忆」——sections/entities 逐条展开、观察草稿区全文、注入上限与 open/archived 统计、dream 固化日志尾部展开(「记录何时被分析过」透明化)、面板直写「记一条」(`memory-observe` 端点,source=`panel`,**用户本人意志不经确认卡**,与 im-send/todo-create 同语义);memory-yzj 未挂载时 tab 显示安装提示。store 加 `memoryView/memoryLog`(repair 检查同步扩展,旧 blob 自愈)。 - **RPC +3**:`memory-scope`(readScope)、`memory-log`(服务新增 `dreamLogTail`,4000 字符行边界截断)、`memory-observe`;`/yzj` 共 41 端点。 - **工具卡**:`memory_*` 五工具进 cards.tsx(observe 确认/scope 计数/search 命中/dream 报告四种形态)。 - **验收**:memory-pane 8 客户端测试(含不可用态、重复 note、失败 note、空日志提示)+ rpc 端点契约测试(`ctx.provide` 挂 fake 服务:scope 投影/log 截断/observe 直写参数、未挂载 fail-closed)+ memory-yzj logTail 行边界测试;`pnpm test` 全仓 237 绿。浏览器走查(六 tab 布局、展开交互、composer)待 web profile 重启后进行。 ### 21.2 dream 开关 + 进程内执行器 + 插件默认模型(2026-08-16 v0.2,设计 §7.1/§7.2 随提交) 用户要求:dream 不应默认开启 + 模型可设置,并建议插件级默认模型统一机器人/dream 等处的模型配置。 - **开关默认关**:`/dream.json`(enabled/provider/model/dailyAt/lastRunDay/lastNote),面板热生效;`enabled=false` 拦 `memory_dream_apply` 工具与执行器(跨进程共享文件,routine 备选路径同拦);observe/read/search/dream_load 不受影响。命名 `DreamSettings`(避免与 service.ts 的 dream 快照 `DreamState` 撞名)。 - **主路径改为进程内执行器**:`dreamRun` 经 `ctx.get('agents')` 创建 one-shot 会话(cwd=vaultRoot、canonical `DREAM_PROMPT`、`whenIdle()` 10 分钟预算、`core.lastDreamReport` 回收报告、in-flight 互斥);每日 `dailyAt` tick(`shouldFireDaily` 纯函数 + `lastRunDay` 戳防重启双发)。动因:实读 dsh-routines 源码确认 routine **无 per-routine 模型字段**——旧路径模型不可控;`memory-dream-routine.yaml` 降为备选(模板头注明差异)。 - **新包 `@dsh-yzj/model-yzj`**(`ctx.yzjModels`,`~/.dsh/yzj-model.json`,get/setDefault/clear/catalog);robot-yzj 解析链尾部接 `fallbackRoute`(会话覆盖 > 机器人配置 > 通道默认 > 插件默认 > harness 默认,建会话现查热生效);dream 模型链 = dream.json > 插件默认 > harness 默认。 - **RPC +7**:`dream-state/dream-set/dream-run` + `model-default(-set/-clear)/model-catalog`;`/yzj` 共 49 端点。记忆 tab dream 区:开关、每日时间、dream 模型选择器、插件默认模型选择器(清空=跟随 harness 默认)、立即固化、上次结果。 - **验收**:model-yzj 4 测试(round-trip/畸形容错/半空拒绝/catalog 透传);dream 5 测试(默认关/局部更新归一化/每日触发边界);memory-pane +4(开关默认关+run 禁用、开关提交、run-now 报告、picker 提交/清除);rpc dream/model 端点契约;全仓 `pnpm test` 251 绿。真实环境验收(开关热生效、dreamRun 全链路、robot 兜底路由)待 web profile 重启后进行。 ### 21.3 记忆组件真机验收(2026-08-16,web profile 重启后实测) - **挂载**:web patch 展开确认(profile node_modules 含 memory-yzj/model-yzj 七包);GUI 3080 在跑。 - **默认关**:`yzj-memory\dream.json` 验收前不存在(= enabled:false 的安全缺省);手写 `{"enabled":true}` 开闸(等价面板开关)。 - **被动注入**:vault 骨架由注入 provider 的首次组装自动创建(无人显式初始化)。 - **全链路(子代理在 GUI 进程内经工具执行)**:observe(obs-20260816211751-c465,open 1/200)→ read → search「周报」命中 → dream_load → dream_apply(提升 1 · 段写 2 · 拒绝 0,无 rev 冲突)→ read 复核(work_context 段建立,观察转 archived)。观察无 rev 属设计(rev 只护 sections/entities 的读改写;观察按 id 一次性处置)。 - **闭环**:固化后的 `work_context` 段在下一轮提示组装中作为 `yzj-memory` runtime-context 出现(验收会话自身可见)——注入现算、无陈旧镜像实证。 - **待用户点验(面板交互,无自动化覆盖)**:记忆 tab「立即固化」(dreamRun 进程内执行器,one-shot dream 会话 + lastNote 回写)与「插件默认模型」选择器(robot 兜底路由热生效)。dream.json 当前 enabled=true 且未设 dailyAt(不自动跑);用户可在面板设每日时间或关闸。 ### 21.4 机器人/记忆管理迁入设置(2026-08-16 v0.3,用户决策) 用户要求:机器人、记忆的管理/配置不要单独占工作台页签,放进设置里。 - **设置 → 云之家**(`settings.section` 插槽,id `yzj`,label「云之家」,order 25):分段控件「机器人|记忆库」复用 RobotPane / MemoryPane(props 不变);包装组件挂载即自取数,RPC verb 包装器更新本地 state——面板内刷新路径(observe 提交、dream 运行、覆盖项编辑)自然重渲染。 - **工作台面板回到四页签**(知识库/日程/会话/待办):`TABS`/`DOCK_ITEMS` 删机器人/记忆,`YzjTab` 收窄,store 删 robot/memory 字段与动作(自愈清单同步收窄,旧 blob 判坏重置);浮动球快捷坞同步。 - **依赖**:ui-yzj 新增 link 依赖 `@deepseek-ai/dsh-client-ui-settings`(仅类型,slot 契约经 `ctx.slots.inject` 延迟注册,无该壳的组合理应静默跳过)。 - **验收**:settings-section 3 组件测试(分段渲染 + 双 pane 挂载自取数 + verb 包装刷新路径);全仓 255 绿;typecheck/build/bundle 通过。真实走查(设置导航出现「云之家」、四页签面板、球坞)待 web profile 重启后进行。 ### 21.5 观察意图标记 durable(2026-08-16 v0.4,设计 §3/D17 随提交) 用户问「agent 怎么标记哪些需要 dream」——此前无 per-observation 意图标记,一切 open 观察都是 dream 候选,由佐证规则判定(agent 写时的判断被丢弃)。 - **`memory_observe` 新增 `durable` 布尔**(frontmatter `durable: true|false`,省略=中性):true=长期候选(dream 单源也可 promote);false=便签(默认 drop,除非新稳定事实被佐证);中性维持原佐证规则。`memory_read`/dream_load digest 显示(长期)/(便签);归档副本保留标记。 - **DREAM_PROMPT 规则更新**(与 routine 模板的差异已在 §7.1 说明同步,模板头注明 keep-in-sync)。 - **面板**:设置 → 云之家 · 记忆库「记一条」加「长期」勾选(勾=durable true;不勾=中性——面板不做便签标记);观察行 meta 显示标记;RPC `memory-observe` 透传 durable。 - **验收**:vault +2(durable 持久化/归档保留)、memory-pane +1(勾选提交 true)、rpc 端点 durable 透传断言;全仓 257 绿。 --- ## 22. v1.8 增补|DSH 唯一会话家园(2026-08-17 产品法;2026-08-16 第一刀绑定;2026-08-16 第二刀融合时间线) 设计基线:[`../spec/dsh-home-session.md`](../spec/dsh-home-session.md)(v1.0 + v1.1 文案)、[`../spec/dsh-home-transcript.md`](../spec/dsh-home-transcript.md)(v1.1 + v1.2 文案 + **v1.3 切会话 UI**)。总方案 v1.8 仅指针;机器人协议 [`../spec/robot-channel-plan.md`](../spec/robot-channel-plan.md) §9 覆盖隐藏平行 session。**本节记录目标 vs 现状。** **文案订正**(2026-08-16):用户可见手势是云之家 @机器人、DSH「发给助手」;说话人「助手」。Claude Tag / @Claude 仅对照类比,不是产品名。行为 / ID / 协议未变。 ### 22.1 现状(第二刀后) | 面 | 现行行为 | 产品法 | |---|---|---| | **绑定表** | ✅ `ctx.yzjHome`(tool-yzj,domain `yzj_home_bindings`):`yzjConversationId` ↔ `dshSessionId` 1:1,重启后同一条。稳定 id `yzj-home-` | 一条云之家会话恰好一条 DSH session | | **消息日志** | ✅ domain `yzj_home_logs`:① inbound / ② dsh-send / backfill;主键 `(yzjConversationId, msgId)`;乐观 `local-*`;T12 跳过机器人 openId | ①② 不是 Session.append | | **DSH 对话** | 挑群 `/yzj home-open` + 回填;`conversation.view`「群工作」按时间戳融合 ①② + ③④ + write-gate pending overlay。IM 行与面板会话 tab 共用渲染器(头像/表情/图文文件/引用)。切会话:缓存先画、miss 不闪「私密会话」、先本地 fused 再 CLI 回填。官方 Chat tab 仍在(harness tab ring,不能替换) | 唯一家园;绑定群时 transcript 含四类节点 | | **Composer** | 绑定:原生发送 = 发给助手(`systemPrompt.context` `yzj-bound-window`);dock「发进群」= ② + `/yzj home-send`,无 user-turn、无确认卡。未绑定:单一发送 + 「丢进群」 | T10/T11 | | **面板 IM composer** | 降为快捷发进群:横幅说明家园在 DSH;发送走 `im-send` → 绑定 log ②。挑群仍 focus 绑定会话 | 面板 = 挑选器/历史/引用;无第二 composer 作家园 | | **召唤窗口** | 云之家 @机器人:`formatSummonWindow` + `agent.inject` 再 followup。DSH 发给助手:`systemPrompt.context` 仅 GUI user-turn。空窗口不注入 | T4/T5 | | **丢进群** | 未绑定 dock「丢进群」:默认勾选近期可见摘要;全文迁移显式;确认模态后 `home-handoff`(② 发群 + followup)并 focus 绑定会话 | D8 | | **write-gate** | 残留 `yzj-robot-*` skip。`ownsConfirm` 的 `yzj-home-*`:GUI user-turn → GUI 卡;plugin / 无 user-message → 群建议卡。绑定家园 `robot_notify` / `robot_continue` 进 WRITE_SPECS(D9) | T13 + D9 | | **机器人 session** | 入站不再分配 `yzj-robot-*` 产品家园;`!fork` / `robot_fork` 打开或恢复绑定会话 | 入站进绑定对象 | 写路径两分(用户发无卡 / agent 发有卡 / 删除强确认)**原则已拍板**(D9),发进群落点在绑定 DSH composer(面板为快捷 ②)。绑定家园上 agent 经 `robot_notify` / `robot_continue` 推群不再绕过确认卡(cleanup:WRITE_SPECS `whenSession=yzj-home-*` + write-gate 认领这两项;面板 `im-send` / `home-send` 仍无卡)。 ### 22.2 阻塞缺口 | # | 缺口 | 现状 | 目标 | 本刀 | |---|---|---|---|---| | G1 | **会话绑定对象** | `ctx.yzjHome` 1:1 表 | 一条云之家会话恰好一条 DSH session | ✅ 关闭 | | G2 | **IM 节点进 transcript** | 绑定会话「群工作」tab 融合 ①②③④;打开回填最近 N;去重 (groupId, msgId) | 绑定会话四类节点共一条流 | ✅ 关闭(官方 Chat tab 仍并存,见下) | | G3 | **确认卡 pending 不进 session 日志** | harness `KNOWN_SESSION_EVENT_TYPES` 白名单;pending 在 host 内存;融合 VIEW overlay `write-list`(SPA 刷新仍在,host 重启降级) | 家园即这条 transcript,挂起的「agent 要发群」必须能在该会话流回放 | 开放(harness 限制;未发明 Session.append 旁路) | | G4 | **fork 开新根 / 丢进群** | `!fork` 交到绑定会话;DSH「丢进群」默认摘要 + 确认模态 + 着陆绑定会话 | 打开或恢复绑定会话;跨群/私聊进群走「丢进群」 | ✅ 关闭 | | G5 | **无群搜索** | 沿用 CLI 最近会话翻页(根 README 已知限制) | 「挑群」要找得到群才能切换绑定会话 | 开放 | | G6 | **面板 composer 移除/降级** | 会话 tab 仍有快捷 IM(写 ② + 横幅);家园在绑定 DSH composer | 发送发生在绑定 DSH 会话。面板 composer 删除或降级 | ✅ 关闭(降级,未删除;挑选器仍需要消息列表) | 非阻塞但相关:免 @ / ambient(D11,本版明确不做);解绑 UI;确认卡同会话合并(仍可选);「群工作」不能设为唯一 Chat(harness `conversation.view` 是 tab ring)。 ### 22.3 验收指针 按 [`dsh-home-session.md`](../spec/dsh-home-session.md) §10 八条: | # | 口径 | 本刀 | |---|---|---| | 1 | 打开群 A 两次 → 一条绑定会话,第二次 focus | ✅ `HomeBindingStore` / `home-open` / 面板挑群 | | 2 | @机器人 followup 进绑定会话,无新 `yzj-robot-*` 家园 | ✅ robot-yzj `resolveSession` | | 3 | 四类节点共一条 transcript | ✅ 「群工作」融合流;官方 Chat 仍在 | | 4 | 用户发群无卡 / agent 发有卡 / 删除强确认 | ✅ 发进群 = home-send / im-send 无卡;agent 写 GUI 或群建议卡;绑定家园 `robot_notify` / `robot_continue` 同闸 | | 5 | 面板挑群切 DSH;无独立 IM 作家园 | ✅ 挑群切 DSH;面板降为快捷 ② | | 6 | 未绑定只有对 agent 的单一发送 | ✅ dock 无「发进群」;有「丢进群」 | | 7 | 丢进群默认摘要 + 确认卡 | ✅ 默认勾选近窗;全文迁移显式;确认后 focus | | 8 | `!fork` / `robot_fork` 不再 `create` 新根 | ✅ 目标改为绑定会话 | **禁止**把 §20 机器人通道「已闭环」读成会话家园已达成——那是协议面。G3(pending 耐久事件)与 G5(群搜索)仍阻塞完整「找得到群 + 刷新后确认卡还在日志里」。 ### 22.4 切会话 UI(2026-08-17) 点任意群/单聊会闪一下:融合视图把初始 `bound: false` 当成未绑定(回填期间闪「私密会话」);面板 cache miss 在新标题下残留上一群消息并打全局「加载中…」。已对齐面板分阶段路径:header 立刻换、缓存同步上屏、miss 清空后只在消息窗 loading、人名/媒体后补。v2.0 群房间时间线沿用同一套分阶段(pitfall-013)。**工作台增补(2026-08-18)**:`conversation.view` 随 session 重挂时左栏用模块 hold、时间线打开滚到底、「加载更早」保位置、图首帧同步读 `file-data` 缓存、H9 `quiet` 不 bump L1。验收:`packages/ui-yzj/tests/transcript.client.spec.tsx`、`packages/ui-yzj/tests/panel-switch.client.spec.tsx`、`packages/ui-yzj/tests/conv-list.client.spec.tsx`、`packages/ui-yzj/tests/im-render.client.spec.tsx`。 --- ## 23. v2.0|群房间 + 话题会话(2026-08-17 拍板;e2e 刀) 设计基线:[`../spec/group-room-topics.md`](../spec/group-room-topics.md)(R1–R22,含 v1.1 工作台)。**本节记录目标 vs 现状。** 本刀:锚定表、入站/交给助手开话题、群房间 IM 视图占住对话格、composer takeover「发进群」、`yzj-topic-*` 写闸、出站帖子进房间日志、面板第二 IM 退役;v1.1 P0 把侧栏树换成入口块 + 工作台两栏 + 话题抽屉。v1.1 P1 精致度六条、P2 四域迁入工作台并退役悬浮球、P3 `TopicRecord.status` 已落地。**视觉刀(2026-08-17)**:tab ring 真藏(pitfall-018)、发进群 portal 进时间线列、dock「发进群」退役、会话行不以「群房间」占位盖 CLI 群名。**宿主生命周期刀(2026-08-17)**:composer portal 改注册/订阅总线(pitfall-019);view-ring observer 收窄到 header;e2e 量不到发送盒即失败。v1.2(2026-08-18):H9 旧宿主 ③④ 迁成「历史对话」话题;H18 抽屉透镜气泡 + 问助手;H4 入站 e2e(未连接 skip);发布口径与根 registry 依赖对齐。**v1.3 布局刀(2026-08-18)**:群房间 opt-in `data-conversation-composer-overlay` 有界视图契约(pitfall-020),三栏内部滚动、打开即触底(wheel/touch 门控的跟随判定);`BOT-` 发送者标「机器人」(原 openId 尾号兜底废弃);机器人长帖折叠「展开全文」;home-nav 分页回填绑定房间真名(「群聊」鬼影行消除);话题官方列表标题改「话题 · 群名」(H10 修订);话题抽屉 340px + 锚点卡 clamp 两行;侧栏脚 dock 视觉重排(图标行 + 当前域高亮 + 机器人状态点)。**v1.3 尾刀**:视图可见名称改「群聊/私聊」(「群房间」保留为设计概念名);话题页重复的回群入口收口到头部锚点卡(chrome 条按钮删除);17 个 pin-only 空壳房间 session 清除 + focus 路径全部走 `homeOpen` 自愈重建(H21)。**v1.4 产品法修订(2026-08-18)**:R20 纠正——官方侧栏「云之家」只收 `yzj-topic-*`(群聊长出的 agent session),`yzj-home-*` 房间不 attach。`attachYzjSession` 按 id 闸门,home-open / topic-open / ask / handoff 已跟。回归 = cwd/RPC 单测。**v1.5 视图归属(同日)**:R22 / H23——话题与普通会话不得挂 IM 壳;只藏「群聊」tab 不够,必须点「对话」清掉持久化 `view=yzj-home`(pitfall-022)。**v1.11 盖层(2026-08-19)**:R27 / H33——工作台是中间栏 DOM 盖层,开面板不建挂钩。**v1.17 入口刀(同日)**:R31 / H40——左边只留一个「云之家」,四域用顶栏页签。 ### 23.1 目标 vs 现状 | # | 面 | 现状 | v2.0 目标 | 状态 | |---|---|---|---|---| | H1 | 基数 | `yzj-home-*` 群房间 + `yzj_topic_anchors` / `ensureTopic` | 1 群 = 1 群房间 + 0..N 话题(R1) | ✅ 关闭(单测) | | H2 | 视图 | **v1.5**:群房间自动切「群聊」并藏 tab ring。话题/未绑定/普通 session **点「对话」**(写入 `view=chat`)并藏「群聊」tab——只 hidden 不够,残留 `view=yzj-home` 仍挂 IM 壳(R22 / pitfall-022)。`YzjRoomShell` 非 `yzj-home-*` 不画。kind 只跟 id 前缀 | 群房间占对话格;话题 = 官方 chat | ✅ 关闭(v1.5 补拨 view + 壳前缀闸;pitfall-018 藏 ring 仍有效) | | H3 | Composer | 群房间 `conversation.composer` takeover 藏官方条;可见面 portal 进时间线列。宿主由 transcript `ref` 注册、composer 订阅(pitfall-019)。dock「发进群」退役(R2) | 群房间唯一动词=发进群;话题唯一动词=问助手;发送条不压会话列表 | ✅ 关闭(takeover + 宿主总线;切工作台域再切回跟到新节点;确认卡 chain priority 更高;发送面见 H14) | | H4 | 话题入口 | 「交给助手」→ `home-topic-open`;@机器人 `resolveSession` 走 `ensureTopic`;回复链续同一话题;丢进群落地房间并开 handoff 话题;发进群 `local-*` ack 后 `retargetAnchor` 到真实 msgId(pitfall-015) | 四入口锚出话题 | ✅ 关闭(router 单测 mint `yzj-topic-*`;`.acceptance/verify-robot-at-topic.mjs`:点 `yzj-dock-home` 开盖层后断言话题抽屉可开。禁止 bash 直调 `yzj-cli` 代发 @) | | H5 | 锚定 | `TopicAnchorStore`:`(groupId, rootMsgId)` + outbound msgId 登记 | R4 锚定表 | ✅ 关闭(单测) | | H6 | 出站帖子 | ack / PushHub / `robot_notify` / 回填写入 `robot-outbound`,标话题回链 | R9:进群房间时间线 | ✅ 关闭(单测) | | H7 | guard / write-gate | `whenSession` 覆盖 `yzj-home-*` 与 `yzj-topic-*` | R10/R11 | ✅ 关闭(单测) | | H8 | 面板 / 悬浮窗 | `shell.overlay` 已摘除;四页签迁入工作台;卡片「查看」切 workbench domain | 第二聊天淘汰;球退役(R16) | ✅ P2 关闭(单测:dock 不再 `openPanel`) | | H9 | 迁移 | 打开群房间时,有真实 ③④ 则幂等 `ensureTopic(..., quiet: true)`;`lastActivity` 用宿主原时间;不搬事件;空白宿主/单聊不迁 | 降为群房间宿主;历史进首条话题;打开不刷列表 | ✅ 关闭(quiet 不 bump;home-open 单测) | | H10 | 侧栏可见 | 话题 `session/title` = `话题 · 群名`。房间保持 blank(R14 v1.8):只在 current 时显「新会话」,点走消失;不进「云之家」分组(R20) | 官方「云之家」能扫出话题、扫不到群聊;挂钩不常驻未分组 | ✅ 标题规则关闭(单测);房间 blank 见 H31 | | H11 | 导航 | **v1.17 / R31**:左边「新建会话」下只有一个「云之家」入口(`yzj-dock-home`),点它 `openWorkbench()` 打开盖层,不切域、不 focus 挂钩。四域是工作台顶栏页签(`yzj-workbench-tab-*` / `setWorkbenchDomain`)。对话 = 会话列表 + 时间线 + 话题抽屉;待办/日程/知识库 embed 原面板。**记忆入口搁置**(R21 v1.6):dock / 工作台 / 设置分段不露,包与工具保留 | 左边一个入口;页签切域;单聊无抽屉;群聊 header「话题 N」开关抽屉 | ✅ P2 关闭;记忆面 v1.6 卸入口;v1.17 收成单入口(dock / room-shell 单测) | | H12 | 模型上下文 | **v1.13**:近窗是一次 plugin inject(`yzj-summon-window` / pre-step),不进 snapshot。记忆仍在 `yzj-memory` snapshot。话题窗走回复链。 | 轨迹里记忆与近窗是两条 plugin 消息 | ✅ 关闭(pre-step + thread + ask inject 单测;pitfall-031) | | H13 | 人名 / openId | CLI 解析 `fromUser.openId/oId/name`;撞键补身份;回填通讯录补名;客户端 `resolveSenders` 与 host 共用 `contact-parse.ts` 拆信封(pitfall-003);时间线禁止「群消息」占位;`BOT-` 前缀发送者标「机器人」(v1.3:机器人不在通讯录,openId 尾号兜底废弃) | 行上是真人名+头像 | ✅ 关闭(单测 + 真机:真人真名、机器人标「机器人」;本 profile 未配置机器人通道时我方助手帖子同样落「机器人」,不伪造「助手」) | | H14 | 轻发送 | 群房间 composer 接 CLI send 全集:回复 / @ / @all / 正文表情 / 图 / 文件;P2 删 72px 留白(pitfall-017 失效:球已退役) | 云之家侧能看见对应回复/@/图文件 | ✅ 关闭(单测;真机需 GUI 重启后 e2e) | | H15 | 群房间视觉 | 布局跟 canvas:自己靠右、他人靠左、hover 出操作;话题回群叠在官方 composer dock(与 InputBar 同宽)。工作台会话行优先 CLI 群名,占位「群房间」不得盖住真名;`session/title` 占位可被真名升级 | 与已拍板原型同一套脸 | ✅ 关闭(2026-08-17 视觉刀 + 回群落 composer 列;单测 + e2e) | | H16 | 云之家 workspace | cwd 仍是 `~/.dsh-yzj/workspace`(房间与话题都建在这,防污染编码区)。**v1.4:`attachYzjSession` 只对 `yzj-topic-*` 调 `attachSession`**;`yzj-home-*` / 其它 id 直接跳过。`ensureYzjHostWorkspace` 顺带 `detachSession` 清掉 v1.1 误挂的房间。robot 通道默认 cwd 同路径。旧会话仍是 `process.cwd()`,attach 失败则吞掉、不分组 | 官方侧栏「云之家」= 话题,不是群聊 | ✅ 关闭(闸 + 存量 detach;cwd 单测:ensure 摘 `yzj-home-*`、留话题) | | H17 | lastActivity / status | `lastActivity` 创建写入、ensure 已有则 touch(H9 `quiet` 除外)。`status`:pending/approved 写 → `confirm`;交付或取消 → `running`(L5);显式 `done`。L2 徽标:accent 数字 = 待确认 > 细点 = 进行中 > 完成无标 | 会话行能反映话题活动与待确认 | ✅ P3 关闭(topics / write-gate / conv-list 单测;quiet 不 bump) | | H18 | 话题抽屉 | 「交给助手」/ chip 开抽屉透镜,不 `focus` 原生;抽屉「原生会话 ↗」才 focus;锚点条反跳高亮时间线且不关抽屉;单聊无抽屉;透镜气泡 + 「问助手」`home-topic-lens` / `home-topic-ask`(用户 `followup`,不 focus) | L3/L6/R17/R19 | ✅ 关闭(抽屉单测:气泡渲染、问助手不 focus、`legacy-host` 无群锚跳转) | | H19 | 群房间精致度 | 同人连发合并、日期分隔、气泡圆角、hover 文字链、助手产物卡、气泡内「N 条回复」chip | §9.1 / §9.5 P1 | ✅ P1 关闭(`room-layout` + transcript 单测) | | H20 | 有界布局 | 视图根带 `data-conversation-composer-overlay`(pitfall-020):三栏各自内部滚动、打开即触底(wheel/touch 门控跟随 + 内容层 ResizeObserver)、composer 钉底;抽屉 340px 有界、锚点卡 clamp 两行;机器人长帖 >240 字折叠「展开全文」;home-nav 对占位房间名分页回填 CLI 真名(60s 缓存) | 房间 = IM 应用的肌肉记忆布局 | ✅ 关闭(v1.3 布局刀;`.acceptance/verify-room-layout.mjs` 全绿) | | H21 | 房间在官方侧栏的去留 | **v1.4 拍板 + 已落地**:群聊本身不进官方侧栏「云之家」;进该分组的是群聊长出的 agent session(话题)。归档藏房间是死路(pitfall-021)。正确手段 = 不 attach 房间;**已挂上的用 `detachSession` 撤回**(ensure 时扫 `yzj-home-*`)。**2026-08-18 清理刀**仍有效:17 个 pin-only 空壳已删;focus 走 `homeOpen` 自愈;房间是临时座位,binding + 插件日志才是真相。R14 空 turn 只防 blank 复用。**同日开发机再清**:停 web GUI 后删 4 个残留 `yzj-home-*` session 目录,并从 `workspace.json`「云之家」成员 / `session_projcache` 去掉对应 id;绑定表与 `yzj_home_logs` / 话题未动。打开群聊会按 homeOpen 自愈重建座位 | 打开群聊 / 重启后「云之家」无该群名行;话题仍在 | ✅ 关闭(闸 + 存量 detach 单测;本机残留房间文件已删) | | H22 | 说明书卸脸 | 话题 chrome 卸掉「下方发送 = 问助手」等式;未绑定 chrome 只留安静「丢进群」链;侧栏脚去 emoji / 去左边框选中、机器人只留状态点;群聊 composer 去 chip 边框、输入圆角;会话列去「会话」头、头像改圆、加载更多改文字链;抽屉空态收成「还没有话题」。**话题回群**:卸掉 header 双行卡 / 挤在标题旁的小字。入口改走官方 `conversation.input.dock`,与 InputBar 卡同宽同圆角,文案只留「回群聊」 | 控件自己说话,密度跟官方侧栏 | ✅ 关闭(chrome / dock / transcript / session-shell 单测) | | H23 | 错画 IM | `conversation.view`「群聊」对每个 session 都在(list 槽无 select)。只藏 tab 时,话题/普通会话若持久化 `view=yzj-home`(点过 tab、或房间切走后没拨回)就整页变成群聊三栏。v1.5:view-ring 点「对话」+ 壳前缀闸 + fused 只把 `kind=room` 当 IM | 只有 `yzj-home-*` 渲染 IM | ✅ 关闭(R22;view-ring / room-shell / transcript 单测;pitfall-022) | | H24 | 工作台首帧 | 侧栏脚「对话」曾 `await homeNav` 再 `homeOpen` 才 focus,冷 CLI / 重开座位时左下角要点很久。现:点「云之家」= `openWorkbench()` 开盖层,不 focus、不换域(R27 / R31) | 点「云之家」立刻出工作台 | ✅ 关闭(dock / overlay 单测) | | H25 | 非对话域发送条 | 待办/日程等仍 focus 房间以挂 `conversation.view`,时间线一卸,发进群 takeover 把卡片画回官方 `composerSeat`。现:域 ≠ 对话时 takeover 仍占位但画 `null` 并收起座位 | 只有对话/群聊有 composer | ✅ 关闭(room-composer 单测) | | H26 | 拖入引用 | 悬浮窗「一切皆可拖」在工作台残留:面板/待办 `draggable` + 全屏 overlay + drop-bus 往 composer 塞 ☁ chip。v1.6 / R23 卸掉拖源、overlay、drop-bus;`conversation.input.dock` 只留回群/丢进群。@ 源不动 | 不能再拖条目进输入框 | ✅ 关闭(面板/待办无 drag;dock 无 insertReference) | | H27 | 他人气泡 | 视觉刀把他人底设成 `--dsw-alias-bg-layer-1`。浅色主题该 token 与画布同白,别人的话看起来没气泡。改为 `--dsw-alias-interactive-bg-hover-solid`(pitfall-023) | 他人 / 助手也有可见 chip | ✅ 关闭(CSS + transcript 单测) | | H28 | 点群开会话 | 会话列每点一行 `homeOpen` + `sessions.open`:卡、未分组多一行、官方超长 composer 闪。v1.7 / R24:点群只切 groupId;`home-fused` / `home-send` / 回填走 groupId;挂钩座位不换。inject 必须把 groupId 传进 `homeFused`(`(id, groupId) => …`),否则点了时间线不换。cache-miss 不得提前 return 卸掉 `#yzj-room-composer-host`(否则官方 InputBar 闪「给智能体发消息」) | 切群立刻出时间线;未分组不增生;loading 仍挂宿主 | ✅ 关闭(conv-list:click 不调 homeOpen;transcript:切 groupId 宿主节点不变) | | H29 | 话题空 turn | 「交给助手」对话题套房间的 `publishHostSession` 空 turn 1;第一次提问再开 turn 1 → 官方 Chat `more than one start Match`。v1.7 / R25:话题只钉标题,不写空 turn | 交给助手后再问,历史能回放 | ✅ 关闭(home-open 单测:话题无 turn/start) | | H30 | 话题问助手损坏 | 抽屉 followup 无 `message.id` → resume `lacks an identified message`;host `agents.create` 不传模型 → `{{model}}` 无值。`identifiedUserMessage` + `topicAgentRoute`(yzjModels / agentDefaultModel) | 问助手后官方 Chat 能打开、能续问 | ✅ 关闭(bound-io / home-open 单测;已坏 session 须停 GUI 后删目录) | | H31 | 挂钩走「新会话」点走就藏 | 试过停写空 turn。真机:focus 到挂钩后窗口标题已是群名,但无 tab ring、`yzj-room-shell` 为 0,并栈溢出。维持空 turn(R14) | 点「对话」必须出工作台 | ✅ 关闭(否决;home-open 仍写空 turn) | | H32 | 未登录入口 | 原先只有工具摘要「请先运行 `yzj-cli auth login`」;home-nav 是本地表,未登录会话列空着。v1.10 / R26:`auth-status` 探测 + `auth-login` 后台拉起 CLI 浏览器登录;工作台会话列 / 非对话域顶栏 / 设置→云之家 登录卡 | 页面上能跳去登录,不用自己开终端 | ✅ 关闭(bridge `start` + RPC + login-banner / conv-list / settings 单测) | | H33 | 工作台挂钩 | 开工作台必须 focus/建 `yzj-home-*` 才能挂 `conversation.view`;入口在侧栏脚。v1.11 / R27:中间栏 DOM 盖层 + 「新建会话」下入口;开面板不造 session;话题仍 `sessions.open` | 开云之家不新建会话;点话题才回官方 Chat | ✅ 关闭(overlay / sidebar-entry / dock 不再 focus;room-shell overlay 模式) | | H34 | 召唤窗每次重贴 / 记忆跟着重发 / 文件没 fileId | GUI 每轮 snapshot 带完整近窗(skip 把 snapshot 当 plugin 又同轮闪掉);整份快照(含 `yzj-memory`)跟着 2741↔577 重发。`messageLine` / 窗口只渲染 `[文件]:名`。v1.12:稳住快照指纹、时间戳带日期、digest 输出 `fileId=` | 续问不再新贴窗/记忆;群附件能按 fileId 下载 | ✅ 关闭(bound-log / home / im 单测;pitfall-029) | | H35 | 话题没有标准工具 | 程序化 `create` 漏挂 preset,裸作用域只有 host 的 `yzj_*`。v1.13 / R28:create/resume mount `agentPresets.defaultId`(standard) | 话题里能读文件 / bash,同时还能发群 | ✅ 关闭(home-open 单测;pitfall-030) | | H36 | 日程永远是 8 月 3 日那条 | 面板/工具一次拉整月。云之家 `calendar event list` 跨天窗口按循环系列折叠,只留窗口内第一次(实测 2 日已丢 18 日那次)。v1.14:按天拆查。v1.15:7 天条带 + 快慢指针(peek 后缀、只信最早日、空尾一停),RPC 与 `yzj_calendar_event_list` 共用 | 打开 8 月能看到各次;今天右侧有今天的会;不再 31 天全打 | ✅ 关闭(calendar-range / events RPC 单测;已登录 tools 冒烟;pitfall-032) | | H37 | 日程/对话不像灵基原型 | 面板日程只有月点 + 右栏列表,无日/周/年;工作台切域只靠侧栏 dock。v1.16:顶栏页签 + 日程四视图(对照 lingee 原型 `.cal` / `calendar-page__tabs`) | 顶栏能切四域;日程能切日/周/月/年 | ✅ 关闭(calendar-pane / room-shell 单测) | | H38 | 话题结果不回云之家话题 | DSH 话题里问助手,回复只留在 DSH;群里锚点回复链是空的。模型偶尔调 `yzj_im_message_send`(还要确认卡),且会把过程也发出去。v1.17 / R29:`agent/status` idle 后 host 以 CLI 本人身份把本轮**最后一条助手正文**回复到 `rootMsgId`;本轮 `write`/`edit` 产物 `file upload` 成功后再写进总结(图进 richText 回复;其它文件因 CLI 不支持 file+reply,跟发群时间线,总结写明落点,pitfall-033)。跳过 plugin 入站 / 已调 `yzj_im_message_send` / 写闸 pending / 假锚点 / 无正文。投递失败不清 watermark,下一轮 idle 可重试。机器人通道本刀不动 | 云之家话题链能看见总结 + 产物;不是每条气泡 | ✅ 关闭(`topic-deliver` 单测 + dsh-2 真机回帖;file 不能进链是 CLI 契约不是漏实现) | | H39 | 话题面板看不到产物 | 云之家 file 不能挂回复链,话题抽屉透镜原先只有文字气泡。v1.17 / R30:透镜把本轮 write/edit 文件画在助手气泡下。R29 发群照旧。助手正文读 `data.message.content` 与 `data.content` | 抽屉里能看见纪要.md 等卡片;群里文件帖仍在 | ✅ 关闭(`topicLensBubbles` 单测 + 抽屉客户端卡) | | H40 | 四域多个侧栏入口 | 侧栏曾并排「对话 / 待办 / 日程 / 知识库」四钮,和官方侧栏抢注意力。v1.17 / R31:左边只留「云之家」;四域改工作台顶栏页签。卡片「查看」仍 `setWorkbenchDomain` | 一个入口 + 页签 | ✅ 关闭(dock 无四钮;room-shell 顶栏页签单测) | 沿用不动:消息日志存储/去重/回填(T1/T7–T9)、召唤窗口(T4/T5)、写路径 D9、群内建议卡(ConfirmBroker)、未绑定私聊与丢进群(D7/D8)。G3 与 G5 继续开放。**v1.17 / R29**:话题 job-done 投递是「问助手」的契约投递面(CLI 本人身份、无确认卡),不是 D9 agent 另起写;agent 显式 `yzj_im_message_send` 仍走确认卡。 ### 23.2 验收指针 按 [`group-room-topics.md`](../spec/group-room-topics.md) §7 + §9.7。H2/H3/H5/H6/H7/H8/H9/H10/H11/H12/H13/H14/H15/H16/H17/H18/H19 有单测。H4 入站话题有 router 单测,`local-*`→真实 msgId 的 `retargetAnchor` 有 topics 单测;真机 `.acceptance/verify-robot-at-topic.mjs`(点 `yzj-dock-home` 开盖层后走抽屉;机器人状态在设置)。真机脚本:`.acceptance/verify-group-room-e2e.mjs`(需运行中 GUI + 已登录 yzj-cli;改 host / browser 后须重启 GUI 再跑,见 AGENTS.md「验收要新实例就重启 GUI」;改 browser TS 后 bundle 前必须先 `tsc -b`,见 pitfall-016)。**v1.1 P0**:入口块 + 会话列表 + 话题抽屉 + `lastActivity` + `~/.dsh-yzj/workspace`。**P1**:时间线精致度六条。**P2**:四域迁入工作台、`shell.overlay` 摘除、72px 留白删除。**P3**:`TopicRecord.status` + L2 徽标 + write-gate L5 回落。**视觉刀**:pitfall-018 tab ring、composer 列、dock 退役、群名占位。**宿主生命周期**:pitfall-019 总线 + view-ring 收窄到 header + e2e 盒子缺失即失败。**v1.2**:H9 历史对话话题、H18 透镜气泡/问助手、H4 skip 型 e2e、发布口径。**v1.3 布局刀**:`.acceptance/verify-room-layout.mjs`(有界三栏 / 触底 / composer 可见 / 无鬼影行 / 机器人标注 / 长帖折叠 / 抽屉有界);pitfall-020(overlay 契约 + 跟随门控);H10 标题改「话题 · 群名」。**v1.4**:R20/H16/H21 云之家分组只进话题;`attachYzjSession` 闸 + cwd/RPC 单测。**v1.5**:R22/H23 话题与普通会话不得挂 IM 壳;view-ring 点「对话」+ `YzjRoomShell` 前缀闸。**v1.6**:R21/H11 记忆入口搁置;R23/H26 拖入引用退役(面板/待办无 drag,`verify-drop.mjs` skip)。**H27**:他人气泡浅色主题可见(pitfall-023)。**v1.7**:R24/H28 点群只切 groupId,不建/不 focus DSH 会话(pitfall-024)。**R25/H29 空 turn**:话题不写空 turn 1(pitfall-025)。**v1.9 / H12**:话题问助手近窗(pitfall-027;`.acceptance/verify-summon-window.mjs`)。**v1.11 / H33**:工作台盖中间栏,开面板不建挂钩(R27 / pitfall-028)。**v1.14 / H36**:日程按天拆查,循环实例不再被整月折叠成第一次(pitfall-032)。**v1.15 / H36**:改成周条带 + 快慢指针,空后缀一次停。**v1.17 / H38**:话题 job-done 投递(`topic-deliver.spec.ts`;dsh-2 真机回帖自跳过若未登录)。**v1.17 / H39**:话题透镜产物卡(`topicLensBubbles` + 抽屉客户端;发群 R29 仍在)。**v1.17 / H40**:侧栏单入口 + 工作台页签(`yzj-dock-home` / `yzj-workbench-tab-*`;dock / room-shell 单测)。 ## 24. AI推进第一期|事元流驱动的推进事项(2026-08-19,设计随提交) 设计基线 [`ai-advance-design.md`](../spec/ai-advance-design.md) v1.0(PRD《AI推进-产品PRD v2.1》+ 灵基原型 lgap17 版引用锚点全文收录于其 §0)。三条硬要求(用户拍板)全部落地: | 面 | 交付 | 证据 | |---|---|---| | 数据模型 | `advance.ts`:事项/事元双表(同「待办任务库」dbt,`sheet table create` 自愈开通,SingleSelect 预注册六态与来源/变化类型);**feed 是唯一变更通道**(无 update/delete 工具),字段级 `原值→新值` diff host 生成;投影(阶段/目标/指标/最新动态)随 feed 折叠回写,读路径以流为准 | `advance.spec.ts` 15 项(fake bridge 有状态存储):建表、幂等、投影折叠、六态流转、非法跳变拒绝且零事元、**时间线无损**(feed N 条翻页读回全量且有序)、judge 用户事元 | | 工具面 | `yzj_advance_list/get/create/feed`(45→49);guard `WRITE_SPECS` +2(create/feed 标准确认,25→27 写门禁) | guard.spec 绿;确认卡 `advance` 域展示变化类型/摘要/阶段流转/原值→新值/refs chips | | 服务/RPC | `ctx.yzjAdvance`(state/get/ensure/create/feed/judge)与 todo 共享 active-library holder(库切换双板跟随);`/yzj` +5 端点(advance-state/get/create/judge/ensure,25→30) | judge 五动词(确认新条件/确认推进→updated/验收→completed/打回→running/忽略→running)全部落 `操作者=user` 事元——D9 直写无卡 | | 独立看板 | **第五页签「推进」**(`WorkbenchDomain` 扩 `advance`,R21/R31 v1.18 修订——推进有真实数据源,与空壳「会议/AI速记」页不同);`advance-pane.tsx` 按 lgap17 信息架构复刻:左队列三组带徽标(待我决定/待我验收/我关注的推进,空态文案沿原型语气)、主详情(kicker+阶段 pill、成功指标卡行、当前有效目标、阶段化决策区、三色时间旅程+来源跳转+查看全部翻页)、右侧信息来源(状态标:已确认/已读取/未达标/等待中)+已有产物+PRD 底注;发起推进弹窗=面板直写立项。**待办页签与 todo-pane 零改动** | `advance-pane.client.spec.tsx` 8 项 + room-shell 五页签断言;全量 551 绿;**真机看板 13/13 PASS**(`verify-advance-board.mjs`,探针 `A-20260819-001`);**六态闭环 10/10 PASS**(2026-08-19 09:48,`.acceptance/verify-advance-loop.mjs`:`A-20260819-003`「闭环探针 105555」draft→running→待我决定→面板确认推进→updated→待我验收→面板确认达到目标→已完成;时间旅程保留立项/确认推进/验收通过,无确认卡、零页面错误;截图 `shots-advance/6–9-loop-*.png`) | **同日旁路真机(发群指定 dsh-2 `6a8400d4e4b09a073e3feeaf`)**:`topic-deliver` live job-done 绿(锚点「【验收】话题 job-done 锚点(R29)」+ 总结回帖 + `r29-summary.md` 跟发时间线)。群房间 e2e `YZJ_E2E_GROUP=dsh-2`:**发进群直写成功**(`【群房间e2e】01:38:12 5zpd`、无确认卡、交给助手开抽屉);旧断言「composer 文案含发进群」FAIL——现行 placeholder 是 `发到 {群名}…`、发送钮是 aria「发进群」图标(`room-composer.tsx`);回复 chip / 幂等「N 条回复」8s 内未出现。`verify-room-layout.mjs` 对 dsh-2:有界三栏 / 触底 / composer 可见 PASS;机器人折叠与抽屉 chip 依赖「金蝶最小DSH交流群」的 BOT 历史,dsh-2 上 0 行属预期。 **分期状态**:①地基已交付;② 事元接入便捷化已交付(§24.1);**③ AI 主动回路本次交付 host/面板切片(§24.2)**;④ 知识沉淀出口、⑤ 归集分析——见设计 §8。 **已知偏差**:(a) AGENTS/本档旧文提到的 `bundle/skills/yzj-cli/SKILL.md` 在当前仓库不存在(历史路径);第一期 agent 教学面由工具 description(立项预填、running 勿打扰、feed 唯一变更通道)与 spec 承载,机器级 skill 的「AI推进」章节待 skill 文件回仓后补。(b) 来源跳转按「可跳则跳」降级:doc 走 web url/知识库域、对话跳对话域、待办跳待办页签,无消息级锚点(CLI 限制,设计 §9-8)。(c) 双写非事务:投影是缓存、流是事实(设计 §9-6,原生后端应服务端折叠)。 ## 24.1 AI推进第二期|事元接入便捷化(2026-08-19,设计随提交) 设计基线 [`ai-advance-design.md`](../spec/ai-advance-design.md) v1.1 §11。不改双表/六态/确认卡;补「人在工作现场把一条信号挂上事项」的用户直写入口。 | 面 | 交付 | 证据 | |---|---|---| | RPC | `/yzj advance-feed`:`actor=user`、`changeType` 固定「进度更新」;**拒绝** `stageTo` / `goal` / `metrics` / `targetDate` / `assignee`(决策 10);有 refs 默认 `sourceType=对话`,否则「人工」 | `rpc.node.spec.ts`:无服务失败闭合;带 stageTo/goal 零调用;refs 过滤空串 | | 群房间 | 消息 hover「喂给推进」(助手帖除外)→ 事项选择器 + 一句话(默认消息前 80 字)→ `refs=[msgId]`、`sourceType=对话`;无 inject 不露按钮 | `transcript.client.spec.tsx`:picker 提交载荷;无 inject 不含「喂给推进」;助手行无按钮 | | 话题透镜 | 锚点旁 / 问助手栏「喂给推进」;草稿作 summary;`legacy-host` 不当 ref;问助手栏仍只 `followup`,两按钮不混 | `topic-drawer.client.spec.tsx`:锚点 feed refs=`m-root`;legacy 无锚点按钮;草稿 feed 且 asked=[] | | 现在反馈 | 看板 kicker「现在反馈」→ `setAdvanceFeedback` + `setWorkbenchDomain('im')`;对话顶非模态事项卡一句话 `sourceType=人工`;取消清卡 | `advance-pane.client.spec.tsx` bus + 切域;`transcript.client.spec.tsx` 卡直写清 bus | | 选择器 | `AdvanceFeedPicker`:列事项、presetId 预选、空板禁用、空摘要拦截 | `advance-feed-picker.client.spec.tsx` | **不做(留给后续切片)**:文档/日程工作台行「喂给推进」;独立巡检 daemon。agent composer chip 喂入仍走 ①期 `yzj_advance_feed` 确认卡。 **已知偏差**:与 §24 (a)(b)(c) 同;另:群房间「喂给推进」是行操作文字链,不是独立 chip 组件(产品文案沿用「喂给推进」,实现是 picker 模态)。 **真机 chrome(2026-08-19,rc.7 web profile 新实例,无 yzj-cli)**:编 harness client+web dist → `dsh web :3080` → `dsh plugin --profile web add -w link:<本仓>`。boot 图含 `@dsh-yzj/bundle/ui-yzj`,`/plugins/@dsh-yzj/bundle/ui-yzj/client.js` 200。新鲜 profile 先关掉内测声明/API Key 卡(pitfall-035)后: | 脚本 | chrome | 写路径 | |---|---|---| | `.acceptance/verify-advance-board.mjs` | **PASS** dock / 五页签「对话 待办 日程 知识库 推进」/ `yzj-advance-pane` 挂上(空态「推进看板还没有开通」+「一键开通」) | **SKIP** exit 0:该环境无 `yzj-cli`(`spawn yzj-cli ENOENT`),登录卡在 | | `.acceptance/verify-advance-feed.mjs` | **PASS** 「推进」页签 + 看板挂上 | 同上;立项 / 「现在反馈」/ hover picker 该轮未跑 | 截图(git 忽略 `shots*/`):`shots-advance/1-tabs.png`、`2-board.png`;`shots-advance-feed/0-advance-tab.png`。ENOENT 不是产品失败。 **真机写路径(2026-08-19,本机 Mac,`yzj-cli` 已登录「单国鑫」,群 = dsh-2,web GUI 重启加载合入后的 `main`)**:`YZJ_E2E_GROUP=dsh-2 node .acceptance/verify-advance-feed.mjs` → **ALL PASS**(含话题透镜)。最新探针「喂入探针 676347」草稿未改阶段:事项卡「真机口头进度」(人工 · 你的判断);「现在反馈」预选后 dsh-2 hover picker 文案含「不改阶段」;话题抽屉打开已有话题,锚点「喂给推进」写入「话题透镜喂入」;问助手栏填「不该发给助手」打开 picker 后取消,透镜里没有 followup。时间旅程同时有卡直写、群房间喂入、话题透镜喂入。脚本要点:切回「推进」须点开该探针;picker 无预选会落到队列第一项。 截图:`shots-advance-feed/1-board-feedback.png`、`2-feedback-card.png`、`3-picker.png`、`4-timeline.png`、`5-topic-lens.png`。 ## 24.2 AI推进第三期|主动回路 host/面板切片(2026-08-19,设计随提交) 设计基线 [`ai-advance-design.md`](../spec/ai-advance-design.md) v1.2 §12。不改双表/六态/D9。host 不做 LLM 语义结论(决策 11);写仍走 `yzj_advance_feed` 确认卡。 | 面 | 交付 | 证据 | |---|---|---| | inspect | 只读 `yzj_advance_inspect`:摊开 open 事项目标/背景/指标/最近事元/合法下一阶段 + 静默/禁止 completed 纪律;`mode=review` 为验收辅助材料 | `advance.spec.ts`:digest 单测 + fake-store 隐藏 completed | | 教学 | feed description 要求先 inspect、无偏差静默、偏差→decision-needed、产物齐→ready-for-review、禁止 completed、话题五步回路 | 工具 description 文本 | | 请 AI 验收 | 看板 kicker → 切对话域 + `advance-ask` 草稿进问助手栏;不自动 followup(决策 12) | `advance-pane.client.spec.tsx`;`topic-drawer.client.spec.tsx` asked=[];真机见下 | | F 巡检挂点 | 不往话题 agent 挂 `schedule_create`(决策 13 / pitfall-007);纪律写在 inspect digest | 文档 | **不做(本切片)**:文档/日程工作台行「喂给推进」;独立 routines daemon;对话向导独立 UI(看板 decision 三按钮 + 话题五步说话已覆盖 D)。 **已知偏差**:与 §24 (a)(b)(c) 同。F 的真实定时仍需用户在 root 会话里自己 `schedule_create`,本切片只提供 inspect 材料与静默纪律。 **门控线后续收窄见 §24.3。** **真机(2026-08-19,本机 Mac,GUI 重启加载③期 bundle,`yzj-cli` 已登录「单国鑫」,群 = dsh-2)**:`pnpm test` 564 绿;`YZJ_E2E_GROUP=dsh-2 node .acceptance/verify-advance-feed.mjs` → **ALL PASS**。探针 `A-20260819-007`「喂入探针 630752」:②期时间旅程(卡直写 / 群房间 / 话题透镜)仍通;kicker「请 AI 验收」切对话、banner「验收问题已预备」、问助手预填 `yzj_advance_inspect` + `不要 stageTo=completed`、透镜无 followup、零页面错误。截图 `shots-advance-feed/6-ask-banner.png`、`7-ask-draft.png`。 ## 24.3 AI推进|打扰判据 + 确认卡门控线收窄(2026-08-19,设计随提交) 设计基线 [`ai-advance-design.md`](../spec/ai-advance-design.md) **v1.3 §13**,决策 14 / 15。缘起:用户指出「让人确认的必须是 AI 发现的重要事情,进度正常不该要确认」——而此前 `yzj_advance_feed` 在 `WRITE_SPECS` 里是**无条件** standard,一条进度备注也弹卡。不改双表/六态/D9/②期用户直写。 | 面 | 交付 | 证据 | |---|---|---| | 门控线(host 固定) | `yzj_advance_feed` 由无条件确认改为 `when: rewritesAdvanceBaseline`——只在载荷含非空 `goal`/`metrics`/`targetDate`/`assignee` 时问;纯追加与阶段变化(→`decision-needed`/→`ready-for-review`)静默落。`yzj_advance_create` 不变(立项是新对象)。写门禁仍 27 条(feed 留在表内,改条件) | `guard.spec.ts` +2:四种静默载荷(含空白基准字段)返回 allow 且 `pending` 为空、四个基准字段各 ask;create 无条件 ask | | 判据(教学面) | `INSPECT_DISCIPLINE` 与 feed description 补:**打扰判据**六条(基准冲突 / 指标掉头 / 按趋势不可达 / 目标日期受威胁 / 需要取舍或授权 / 路径分叉)、**静默判据**、**抑制**(同判据不重复提、同来源去重、被 ignore 过不再提)、**验收判据**(N/N + 产物齐 + 无未决偏差)、门控线一句 | `advance.spec.ts` digest 断言五条锚点;全量 **566 绿** | | 分工 | 「重不重要」由 AI 判断,但只能表达为**阶段**;「要不要过卡」是 host 固定规则,模型不可绕(决策 15) | 设计 §13.5;host 仍不做语义结论(决策 11) | **为什么阶段变化也不弹卡**:偏差 feed 的落点就是看板「待我决定」,那里本来就要人拍板(确认推进 / 忽略)。此时再弹一张卡=同一件事问两遍,且第一遍「我能写这条吗」没有信息量。卡留给「改基准」——目标/指标/目标日期/负责人一换,后续所有比对的锚点就换了,人没看过就换,AI 之后的判断无从校验。 **已知偏差 / 代价**:静默 feed 把噪音代价前移到事元表——纪律(§13.2/§13.3)是教学面,host 不强制;v1.4 已把同源去重升为 host 强制(决策 19),频率上限仍观察噪音后再定。真机卡面走查未重跑(本次改的是 ask 与否的判定,`guard.spec` 已覆盖;卡面渲染未变)。 ## 24.4 AI推进|主动发现 scan → inspect → feed(2026-08-19,设计随提交) 设计基线 [`ai-advance-design.md`](../spec/ai-advance-design.md) **v1.4 §14**,决策 16–19。把机制 B/F 从「被召唤时比对」升级为「AI 定时自己发现」。不改双表/六态/D9/决策 10–15。发现通道是 CLI `im message list --type new` 轮询,不是机器人 WS(协议只投 @机器人)。 | 面 | 交付 | 证据 | |---|---|---| | scan 工具 | 只读 `yzj_advance_scan`(50→51):`groups` 必填 1–8;首扫 `type=newest` 建基线不回灌;增量 `type=new`;过滤本人/`BOT-`;cursor 写 storage-domain `yzj_advance_scan_cursors` | `advance.spec.ts`:基线 / 静默轮 / 过滤自身 / cursor 持久 / 未知群 | | host 去重 | `coreFeedAdvance` 在 `appendEntry` 前:`input.refs` 与已有事元 refs 有交集 → 幂等返回、不加行(空 refs 不去重) | `advance.spec.ts`:同 msgId 二次 feed 不加行;无 refs 仍追加 | | 巡检教学 | `INSPECT_DISCIPLINE` + scan/inspect/feed description 含巡检五步;用户说「开启巡检」→ root `schedule_create(every_seconds≥300)` | digest 断言「巡检五步」;scan 不在 `WRITE_SPECS` | | schedule 挂载 | bundle `cordis.patch.yml` 加 `id: time-context` / `id: schedule`(与官方 `examples/web-schedule` 同 id,防双挂) | 插件 id 与 overlay 对齐;诚实边界:session-local,GUI 关就停 | | 无人值守 | `docs/spec/advance-patrol-routine.yaml` + `docs/spec/headless-yzj.cordis.yml`(只挂 bridge+tool-yzj)。digest 降噪:routines 每轮都投 chatnode,无内容过滤 → 默认只 `file` deliver;无发现输出 `[advance-patrol:quiet]` | 模板头写明 spike 结论 | | 看板状态行 | `/yzj advance-scan-state` + 队列头 `data-testid="yzj-advance-scan-status"`(尚未巡检 / 上次巡检 HH:mm · 本轮发现 N 条) | `advance-pane.client.spec.tsx` + `rpc.node.spec.ts` | **已知偏差**:频率上限未做(决策 19 观察项)。sidecar 扫描走独立 `ScanCursorStore`(内存),不会写 GUI 进程的 cursor domain——看板「上次巡检」只在 GUI 内 `yzj_advance_scan` 之后更新。schedule 仅对新创建的 live root 生效(已有 root 需重开或新会话)。 **真机闭环(2026-08-19 13:22,群 dsh-2 `6a8400d4e4b09a073e3feeaf`)**:sidecar `tsx .acceptance/advance-patrol-driver.ts` 把 cursor 回拨到最新非机器人消息之前 → `yzj_advance_scan` 扫到 1 条真信号 `6a850dc2e4b0b5c46221e6f6`(`[文件]:r29-summary.md`,09:58)→ inspect digest 含该 `` → 立项 `A-20260819-008`「巡检闭环 945125」并 feed 进度更新(refs=该 msgId)→ 第二次同 ref feed `idempotent:true`、事元仍 3 条。`E2E_HEADED=1 node .acceptance/verify-advance-patrol.mjs` → **ALL PASS**:看板「我关注的推进」出现该事项,时间旅程第三行「巡检发现:群「dsh-2」[文件]:r29-summary.md」,信息来源「已读取」。截图 `.acceptance/shots-advance-patrol/1-patrol-board.png`。队列头仍「尚未巡检」——scan 跑在 sidecar 进程,不写 GUI 的 cursor domain;要让状态行跳「上次巡检」需在 root 会话里让模型调用 `yzj_advance_scan`。 ## 24.5 AI推进|v1.5 意图线程订阅模型 + MVP→灵基迁移合同(2026-08-19,纯文档,无代码) 出处:0819 14:00 产品方案讨论会(转录 `转录:AI推进产品方案讨论 20260819 1400.txt`,会上确认三概念定型、命名口径、两个待补交付物)+ 用户旅程口述定稿。 | 面 | 交付 | |---|---| | 设计 | [`ai-advance-design.md`](../spec/ai-advance-design.md) 升 **v1.5**:§15 意图线程订阅模型(两类线程 / `yzj_advance_threads` demo 落位 / 渠道级 cursor 一次取流多事项分发 / Work+Dream 双节奏 / 策略选择文本约定);决策 20–24 入表;分期表加 ③.2(待排) | | 迁移合同 | 新增 [`../migration/advance-lingee-migration.md`](../migration/advance-lingee-migration.md):MVP↔灵基 = 「合同+证据→重建」;三层拆分(合同/机制形状/脚手架)、五断层、验证清单、「存钱 vs 镀金」取舍原则、灵基需求清单 | | 图 | `docs/diagrams/advance-6-journey`(用户旅程按口述重画:意图线程×N 订阅、手动喂/关联两条路径、待我决定/待我验收双出口)。**图集清理**:删 `advance-2-lifecycle`(被 6-journey + 3-gate 覆盖)与 `advance-4-dream`(「巡检唤醒 Dream」触发关系被决策 21 双节奏取代);`advance-1` 输入改「意图线程订阅」;`advance-7` 补第六块「策略选择结构化」。编号留空号不重排;图集已登记 docs/README.md | **实现缺口(③.2,已于 §24.7 落地)**:`yzj_advance_threads`、面板「关联渠道」入口、scan 按订阅取流分发、决策区 `选项N` 渲染均已实现;feed 带 `subscribe` 与单文档源内容更新监测仍后置(见 §24.7 已知偏差)。 **正式开发交付面(同日晚补,已发 830 群;汇报产物不留仓库——用户拍板)**:接口数据契约 v1.0(自 spec v1.5 提炼的三对象字段级 + 状态机 + 门控 + 判据 + 接口面 + 平台需求八条快照)、中国新网故事线文字版(10 项任务分摊 / AI 自动 7 / 人 4 次判断 / 干预入口 / 节奏边界)、系统架构蓝图 / 产品模块关系图 / 故事线图三张。五件已发群「830 项目【登顶计划】」(`6a605c7ce4b0772a6279295e`):文本消息 `6a856f0ce4b08c3f7f34d036`(含外部协助三件事:灵基平台八项排期 / 约王健对齐 / AI 速记结构化访问),文件消息 `6a856f0ee4b0892254769fbe`(架构蓝图 png)/ `6a856f0fe4b0e1cfb89cc528`(模块关系 png)/ `6a856f11e4b0e01177c0c896`(故事线 png)/ `6a856f12e4b00a134059b32e`(契约 md)/ `6a856f12e4b0a35e3fd4b583`(故事线文字版 md),2026-08-19 16:51。**这些文件只存在于群消息,仓库不保留副本**;合同唯一事实源 = spec v1.5 + advance-lingee-migration。 ## 24.6 AI推进|830 真数据闭环实验(2026-08-19,执行人:agent) 实验脚本:[`.acceptance/advance-830-experiment.md`](../../.acceptance/advance-830-experiment.md);driver:`advance-830-wave1.mjs` / `advance-830-wave1-fix.mjs` / `advance-830-wave2.mjs`;截图:`.acceptance/shots-advance-830/`。 **环境**:GUI 3080 于 18:22 重启(cursor 回拨需新进程加载);cursor 回拨至 `6a83ffffe4b09a073e3f481a`(农佳捷需求前一条,8/18 14:47)。**模型为 MiMo V2.5**(实验文档写 DeepSeek-V4-Pro;执行时经发起人拍板沿用当前档位 MiMo V2.5)。**会话权限档位必须 Workspace Write**——Full access = approval never,ask 自动转 deny(新坑 [pitfall-036](../pitfalls/pitfall-036-full-access-disables-approval.md),首轮四连发全灭后定位)。 **第 0 波(知识底座)**:4 篇四段式纪要入「我的知识/830实验·共识」(父 `6a8572c1fcb8644499540553`)——0806 `6a85774aecd3fb103b859f8a`、0812 日例会 `6a85774bfcb86444995406ed`、0813 方案会 `6a85774dfcb86444995406ee`、0819 产品会 `6a85774eecd3fb103b859f8b`。原料=群文件转录 3 份(file download)+ docx 智能纪要 1 份(textutil 解析)+ 本地 0819 转录;人工读转录写纪要,全程 yzj-cli 只写个人知识库。 **第 1 波(立项+回放)**:root Chat 新会话四连发。立项 `A-20260819-002`「830:从参谋部到 AI推进」弹卡①确认;② 回放(refs=0806+0812 docId)静默落;③ 目标更新**首次 feed 被 host refs 去重误吞**(refs 与 ② 的 0812 docId 交集 → 幂等返回不加行,模型追问,弹卡②确认的写未生效)→ 补救换 refs=8/12 定义卡 msgId `6a7c1274e4b09a073bec3d4d` 重 feed,弹卡③确认,goal 更新为「按 AI推进产品定义:六态看板+最小推进回路,跑通纪要→共识入库→下一步编排」;④ 0813 回放(refs=0813 docId)静默落。终态时间旅程 4 行 + 目标区新 goal + 指标卡三行(截图 `10-detail-after-fix.png`)。 **第 2 波(真巡检)**:cursor 回拨 + 重启后新会话发 §5 原文 prompt(MiMo V2.5,加「不要询问」行为指令,无结果暗示)。一轮 scan 覆盖(limit=20,过滤本人/`BOT-` 后 16 条候选):队列头「上次巡检 18:26 · 本轮发现 20 条」(截图 `w2-3`);模型 inspect 比对后**静默 feed 一条进度更新**(「PRD v2.1 已产出并分享;0819 评审会已开」),refs 7 个含农佳捷需求 `6a841a46e4b0ab2392c31eb9` 与 PRD `6a842792e4b08c3f7ebf8521`;竞争力报告线(廖衍清等 4 条)被明确抑制(模型汇报原文:「竞争力报告、npm cli 安装、图片/文件等 13 条信号与 AI推进目标无关,已抑制」);本人 16:51 六条交付不在 refs。**巡检波 0 张确认卡**(静默纪律成立)。幂等测试:同 refs 二次 feed → host 幂等返回,`yzj_advance_get` 事元总数 5 不变(截图 `w2-5`)。 **判定总表**: | # | 判定项 | 结果 | 证据 | |---|---|---|---| | 1 | 知识底座 ≥3 篇四段式纪要 | **PASS** | 4 篇 docId 如上;父目录「830实验·共识」 | | 2 | 立项经一张确认卡 | **PASS** | `1-create-card-1.png`;A-20260819-002 | | 3 | 时间旅程 ≥4 行且 8/12 目标更新弹卡 | **PASS(含补救)** | 4 行旅程 + 目标更新卡(首试被 refs 去重误吞,补救换 msgId ref 后成功;详见判定 9) | | 4 | 队列头「上次巡检 · 发现 N≥1 条」 | **PASS** | 「上次巡检 18:26 · 本轮发现 20 条」`w2-3-board-after-scan.png` | | 5 | 农佳捷需求/PRD 入 refs | **PASS** | 两个 msgId 均在详情 refs;`w2-4-detail-after-scan.png` | | 6 | 竞争力报告噪音拒绝 | **PASS** | 详情零「竞争力」事元;模型抑制汇报见会话 | | 7 | 本人 16:51 六条过滤 | **PASS** | 六个 msgId 均不在 refs | | 8 | 幂等 | **PASS** | 二次 feed 同 refs → 事元 5 条不变;`w2-5-idem-done.png` | | 9 | 确认卡恰好 2 张 | **FAIL(实际 3 张)** | 立项① + 目标更新首试②(确认的写被 refs 去重吞掉、未生效)+ 目标更新补救③。门控线本身全部正确(纯追加/巡检静默、基准变更弹卡);多出的卡是**机制误伤**的补救成本 | **结论(打扰判据精度首份真机证据)**:静默/打扰边界在真数据上成立——巡检波 16 条候选信号里模型只喂 1 条合并进度更新(零打扰),噪音全拒、自身全滤;判据文本与 `INSPECT_DISCIPLINE` 教学在 MiMo V2.5 上有效。**唯一机制缺陷:host refs 去重粒度**——「refs 有交集 → 整体幂等」误伤「不同事元合法引用同一文档」(②③ 都引 0812 纪要是合理的)。建议(待拍板,未改代码):(a) 去重仅对 msgId 类信号 ref 生效,docId 引用不参与;或 (b) 幂等返回显式区分「完全重复」与「部分 refs 重叠」(后者应追加并提示重叠 refs),让模型当场可继续而不是追问中断。此项建议同步影响 §13 判据文本/`INSPECT_DISCIPLINE` 的 refs 选用指引。 **修复闭环(同日晚,决策 25)**:去重口径收窄为「refs 集合完全相等 + 同一 changeType 才算重放」(`isRefReplay`),部分重叠正常追加并返回 `overlappedRefs` 提示(`overlappedRefsOf`);feed description 与 spec 决策 19/25、§13.3/§15.3、tool-yzj README 同步。单测 +3(830 回归用例:子集重叠追加带提示 / 同 refs 异 changeType 追加 / 超集追加 / 完全重放仍幂等;纯函数 `isRefReplay`/`overlappedRefsOf` 断言),全量 578 绿。真机回归(`advance-830-regression.mjs`):巡检会话重放同一组 7 refs + 同 changeType → 幂等返回、事元仍 5 条(E-20260819-018 唯一承载),全程无确认卡(截图 `regression-idem.png`)。判定 9 的「3 张卡」维持历史事实不改写;若重跑第 1 波,③ 场景下应为恰好 2 张。 **同一晚的连环修正(诚实记录)**: 1. **回归证据当时无效**:上述真机回归实际跑在 worktree 旧 bundle 上——web profile 的 `@dsh-yzj/bundle` link 被③.2 开发切到 `~/.qoder/worktree/…` 未归位(新坑 [pitfall-038](../pitfalls/pitfall-038-profile-bundle-link-stale.md))。完全重放在新旧语义下都幂等,故结论巧合成立;决策 25 的有效真机证据 = 单测 3 用例 + 下文过滤修复验证。link 已归位主 checkout。 2. **判定 7 的 digest 层真相**:scan 的本人过滤(`whoamiOpenId`)因 `contact user get` 返回顶层裸数组而解析失配,selfOpenId 恒空——**digest 一直含本人消息**,判定 7 的 PASS 只证明了 refs 层(模型抑制纪律兜底),③.2 走查时模型把本人 19:22 报告当信号分析而暴露(pitfall-003 增补实例:mock 形状照错误假设写,单测绿真机挂)。已修:解析层裸数组优先兼容 `{list}`,fake store 改实测形状形成回归保护;真机验证(`advance-830-self-filter.mjs`,cursor 回拨 18:11 重扫):本人 19:22/19:23 两条不再出现在 digest,19:42 非本人图片正常进入,ALL PASS。 3. **遗留观察(limit 截断)**:第 2 波 scan limit=20 一轮覆盖 27 条候选时,17:18–18:11 的 5 条晚到信号(农佳捷「工作现场」补充等)疑似未被任何一轮 feed/显式抑制——模型未触发第二轮 scan(§5 允许的「再扫一轮」依赖模型自报增量)。此为主动回路的覆盖度边界,记入③.2 后续观察。 **遗留观察**:实验期间看板出现非本实验的探针事项(「线程探针 910289」18:05、「喂入探针 532538/928101/187603」18:16–18:27,为并行走查产物),不影响判定;实验现场(A-20260819-002 与「830实验·共识」目录)按 §9.1.4 保留,清理由 Guoxin Shan 决定。 **结果同步(§9.2.1,19:22–19:23)**:实验报告 + 看板最终态图已发 830 群(文本 `6a8591fee4b0f812dd4eda8c` / 图 `6a85921ae4b098e1531d3d4a`),兑现 16:51 预告的「跑通后出实验报告」。 ## 24.7 AI推进|③.2 意图线程订阅(2026-08-19,设计随提交) 设计基线 [`ai-advance-design.md`](../spec/ai-advance-design.md) **v1.5 §15**,决策 20 / 21 / 23。不改双表 schema / 六态 / 门控线 / feed 唯一变更通道;订阅承载在 host storage-domain,写路径只有两条:agent 立项参数(既有卡)+ 面板直写(D9 无卡)。 | 面 | 交付 | 证据 | |---|---|---| | 订阅注册表 | `tool-yzj/src/advance-threads.ts`:storage-domain `yzj_advance_threads`(v0)`advanceId → [{ token, kind, label, addedBy, addedAt }]`;token 字面量正则 `im:/doc:/todo:/event:/file:`;`im:` = persistent,其余 = document;内存垫底直到 `open()`(同 scan-cursors 范式) | `advance.spec.ts`:token 语法 / kind / 来源类型映射单测 | | create 挂线程① | `yzj_advance_create` 新增可选 `threads` 参数(schema 字面量,pitfall-009);非法 token 跳过;im: 标签写入时经群目录解析一次;digest 回报「已订阅线程」。`WRITE_SPECS` 不变(create 本就标准卡) | `advance.spec.ts`:带 threads 立项 → 注册表行(addedBy=agent、label=群名);bogus token 被丢弃 | | scan 聚合订阅 | `yzj_advance_scan` 的 `groups` 改为可选:缺省时聚合全部 open 事项的 `im:` 线程去重(completed 事项不进集合);超过 8 个渠道报错提示分批(决策 17 刚性,不悄悄截断);无订阅时报错带指引;digest 新增「订阅清单」行(每事项 token 列表)供模型分发;cursor 机制零改动(渠道级共享) | `advance.spec.ts`:同一群被两事项订阅 → `im message list` 恰好一次、cursor 只前进一次、两事项各自出现在订阅清单;completed 的订阅不进扫描集合;无订阅报错指引 | | 单文档源关联 | `advance-thread-add` 对 document 类追加一条 `备注` 事元(来源类型按 token 映射:doc/file→文档、todo→待办、event→日程;refs=[token]);重复关联被注册表 + 决策 19 同源去重双重幂等挡住 | `advance.spec.ts`:关联 doc → 一条 user 备注事元;重复关联不加行;解除只删注册表行、事元不动 | | 服务面 + RPC | `ctx.yzjAdvance` 新增 `threadsOf` / `threadAdd` / `threadRemove`;`/yzj` +2 端点 `advance-thread-add` / `advance-thread-remove`(用户直写,无卡);线程清单折进 `advance-get` 响应的 `threads` 字段,不另开读端点;`openNow` 同时打开两个 domain | `rpc.node.spec.ts`:两端点缺服务/缺载荷/服务报错/透传四类契约 + advance-get threads 折叠 | | 面板 | 详情右栏顶部「订阅渠道」区:线程 chips(`data-testid="yzj-advance-threads"`,群/文/待/日/附图标 + 你关联/AI 关联 + × 解除)+「关联渠道」弹层(群 picker 复用 groups RPC + 手输 token 兜底);决策区解析最新决策请求事元的 `选项N` 行渲染按钮(点击 = judge confirm_advance 带 note=选项全文),`影响` 行单独展示,无选项行时既有三动词原样 | `advance-pane.client.spec.tsx`:chips 渲染/解除、弹层群 picker/手输 token、选项按钮落 note、无选项回归 + `parseDecisionOptions` 单测 | | 教学面 | `INSPECT_DISCIPLINE` 补订阅分发一句;create description 写「在群话题里立项时带 threads=[im:]」;scan description 写 groups 可选 + 订阅聚合语义 | 工具 description 文本;digest 断言「订阅清单」 | **真机(2026-08-19,本机 Mac,GUI 重启加载 worktree bundle,`yzj-cli` 已登录)**:`pnpm test` **592 绿**(基线 575 + 新增 17)。`node .acceptance/verify-advance-threads.mjs` → **ALL PASS**:sidecar 探针 `A-20260819-001`「线程探针 910289」走到 decision-needed → 决策区渲染 选项1/选项2 按钮 + 影响行、既有三动词仍在 → 点选项2 落 user 事元「确认推进:目标日期顺延两周」(你的判断)→ 关联渠道弹层群 picker(10 群)关联后 chip 出现、× 解除 → 手输 `doc:e2e-probe-doc` 落一条备注事元「关联渠道:e2e-probe-doc」。零页面错误。截图 `.acceptance/shots-advance-threads/1-decision-options.png` — `4-doc-thread.png`。**既有 E2E 回归**:`YZJ_E2E_GROUP=dsh-2 node .acceptance/verify-advance-feed.mjs` → ALL PASS(②③期现在反馈/事项卡/群房间喂入/picker 全通;话题步骤自跳过,见 pitfall-037:dsh-2 当前无话题锚点,属数据态非回归);另以有话题的 830 群走查话题链路(抽屉 → 透镜 → 喂给推进 picker → 问助手预填不 followup)全绿。 **已知偏差**:(a) agent 在 feed 里带 `subscribe` 意图(§15.2 提及)本切片未做,订阅写路径只有 create 参数 + 面板直写两条(计划内排除);(b) 单文档源只做「关联即一条事元」,内容更新监测未排期(计划内排除,spec §15.1 已注);(c) Dream 每日节奏未落地(④期配套,本切片只保证 scan 聚合可被任何节奏调用);(d) 浏览器验收的线程①演示走用户关联路径(storage-domain 注册表是 GUI 进程私有的,sidecar 写入对 GUI 不可见,同 §24.4 sidecar cursor 局限)——立项挂线程①与「同群两事项一次取流」由 fake CLI 单测覆盖;(e) 线程 chip 未展示「最近取流时间」(§15.2 投影句的可选细节,cursor domain 未按线程反查,后置);(f) vitest client 测试的 harness 源 alias 在无兄弟 checkout的 worktree 下回退到 `~/dev/deepseek-harness`(`DSH_HARNESS_ROOT` 可覆盖)——环境适配,不改变「兄弟 checkout 是唯一事实源」语义。 ## 24.8 AI推进|④期知识沉淀出口 + 第七态 cancelled(2026-08-19,设计随提交) 设计基线 [`ai-advance-design.md`](../spec/ai-advance-design.md) **v1.6 §16**,决策 26–31(同日拍板:复盘=终局收口、面板不做独立沉淀按钮、一批一次确认、dream 只改 prompt、落点「推进复盘/<事项名>」、工具面零新增)。830 实验第 0 波人工基线(10 分钟/4 篇)是④期自动化收益的对照。 | 面 | 交付 | 证据 | |---|---|---| | 第七态 cancelled | `cancelled`(已中止)入状态机:非终态均可达、`cancelled→running` 可重启;judge 第六动词 `cancel`(用户直写无卡,D9);open 队列/scan 订阅聚合/inspect 全排终局(`isOpenStage` 统一);**终局 host 强制**:agent `stageTo=completed/cancelled` 一律拒绝(actor≠user)——顺带补齐 spec §13.5 早声称「状态机拒绝 completed」而代码未拦的偏差 | `advance.spec.ts` +5:cancel 落 user 事元/重启、legacy 库缺选项明示报错、agent 终局拦截、状态机边、list open 排除 | | 存量表 schema 守卫 | `assertStageOption`:写 cancelled 前读 `sheet get` 校验「阶段」SingleSelect 选项(实测形状 `fields[].data.items[].value`),缺则明示引导补选项,不静默丢(迁移文档 §3 事实 5 / pitfall-003) | 真机走查命中(见下) | | 面板 | STAGE_LABEL「已中止」+ dot 灰;队列排除终局;决策区底部低强调「中止推进」(二次确认态「确认中止?再点一次」);终局(completed/cancelled)渲染「沉淀复盘」入口(跳对话域预填,复用「请 AI 验收」bus 模式) | `advance-pane.client.spec.tsx` +2:终局提示写 draft、二次确认;queuesOf 语义更新(终局不进队列,spec §2) | | 教学面 | `INSPECT_DISCIPLINE` 补沉淀四步/纪要四步;feed description 同步(七态+终局禁止+沉淀流程);模板两份落 `docs/spec/advance-review-template.md`(五段)/ `meeting-minutes-template.md`(金蝶四段式) | 文本断言随既有 digest 用例 | | dream 取材 | `DREAM_PROMPT` 补推进事项取材指引(yzj_advance_list/get 读终局事项产物事元),放开「只用 memory_*」为「memory_* + yzj_advance_*(只读)」(决策 29) | `memory-yzj/src/dream.ts` | **真机(2026-08-19 晚,本机 Mac,GUI 重启加载 main 合并后 bundle)**:`pnpm test` **602 绿**(595+7);`node .acceptance/verify-advance-terminal.mjs` → **ALL PASS**:面板直写探针「终局探针」立项(无卡)→ 详情「中止推进」二次确认态正确 → judge cancel 撞上存量库缺 cancelled 选项,`assertStageOption` 明示引导(「请在多维表格给该字段补加选项 cancelled 后重试」)——不静默丢的诚实路径按设计工作。截图 `shots-advance-terminal/1-3`。 **存量库升级(同日晚,用户拍板「删掉重新加」)**:CLI 无补选项口子(实测:运行期写未注册值回读为空串,静默丢弃今日仍成立;`sheets/update` 端点仅供 rename)→ 对推进库做**备份→删「事项」表→按最新 itemFieldsJson 七态重建→导回**:事项 7 条字段级零差异、事元 24 条未动、阶段选项含 cancelled。备份留 `/tmp/yzj-advance-backup/`。升级后重跑 `verify-advance-terminal.mjs` → **ALL PASS**:探针中止 → 已中止 → 终局提示「沉淀复盘」→ 队列排除 → 跳对话域 banner「复盘沉淀已预备」。截图 `shots-advance-terminal/4-cancelled.png`、`5-export-review.png`。 **已知边界(计划内)**:(a) ~~存量推进库需手工补 cancelled 选项~~ 已由备份-重建-导回完成(见上);(b) 终局事项从队列排除后详情不可再打开,「沉淀复盘」提示只在收口当刻可见(决策 26:主路径是用户口述);(c) 复盘/纪要的批量落待办(决策 28)与面板直写一键沉淀(决策 26 明确不做)均未实现,属教学面口径。(d) 面板 judge 区「中止推进」按钮本期无单测覆盖 busy 态(二次确认已覆盖)。(e) banner 文案按 draft kind 区分(验收/复盘)——复用 bus 时记得带 kind,否则误导(本日走查抓到,已修)。 ## 24.9 AI推进|面板 UX 打磨(2026-08-20,v1.6 续) 缘起:用户走查后点名「事元溯源点击跳转做好一点、缺按钮、不合理设计都看看」。布局锚点用户现场确认:中栏=推进时间线、右栏=意图线程(订阅渠道)+事元(信息来源/产物)——本次未动布局结构。 | 面 | 交付 | 证据 | |---|---|---| | refs 溯源可点化 | 时间旅程 refs 从裸文本(`yzj:6a85…` 长串、不可点)改为 chips:剥 `yzj:` 前缀(模型按工具 description 字面误加的前缀)+ 类型图标(文/聊/待/程)+ 短 id;**doc → 知识库 web 直跳**(`window.open` 真链接,hover 见全 id),msg/todo/event → 跳对应域(无消息级锚点,决策 8 诚实降级);同值去重(巡检合并 feed 的重复 ref 只渲一次)。sources 区与已有产物区条目同样可点 | `advance-pane.client.spec.tsx` +1(doc chip 是 含 docId 直跳、msg chip 点击切 im 域);真机 `shots-advance-ux/audit-1-top.png` | | 已结束折叠区 | 队列底部「▸ 已结束 N」:终局(completed/cancelled)事项不再蒸发,展开可点进详情——④期边界 (b)「终局提示只在收口当刻可见」就此补上(事后可达);终局条目弱化显示 | 单测 +1(toggle 展开→点进→终局提示出现);真机 `audit-3-closed.png` / `audit-4-closed-detail.png` | | 立即巡检入口 | 队列头状态行旁「巡检」按钮 → 跳对话域预填巡检 prompt(复用 ask bus,新 kind='patrol')——巡检不再只能靠 schedule/口述全文 | 单测 +1(draft kind=patrol、切 im 域) | | banner 文案分流 | ask banner 按 kind 区分「验收问题已预备 / 复盘沉淀已预备 / 巡检请求已预备」;patrol 无事项时不显示空括号 | 走查抓到文案写死后修复 | 全量 606 绿。**产物区收掉(用户拍板 2026-08-20)**:「已有产物」区(sources 的文档类子集聚合)从右栏移除——产物是事元的一部分,随「当前判断来自哪里」呈现;spec §7 sideHtml 口径已同步。右栏自此只有意图线程(订阅渠道)+ 事元(信息来源)两区。 **事元来源区窗口化(同日续)**:「当前判断来自哪里」默认只显示最近 3 条 +「展开全部 N 条 / 收起」(与时间旅程「查看全部」同型);意图线程的加(关联渠道弹层)/去(chip ×)为既有能力,真机确认在位。607 绿。 **目录级订阅(同日续,决策 32,用户拍板「知识库一整个才能自动获取增量」)**:token 词汇加 **`dir:`**(知识库目录节点;整库=库根目录 `dir:`),kind=persistent 进持续渠道——scan 聚合时按 `doc list --parent-id` 取增量(首扫快照 docId→updateTime 建基线不回灌;增量=新增/更新文档,信号 refs=、sourceType=文档);cursor 存 scan domain 新 `dirs` 表。关联弹层**去掉手输 token**(开发者界面不是用户界面):只留 IM 群 picker + 知识库目录 picker(「我的知识(整库)」+ 一层 hasChildren 目录);chip 图标加「库」。单测 +3(dir 扫描全生命周期:基线/新增/更新/静默;弹层无手输+目录 picker+dir 关联;threadKindOf dir=persistent);真机:弹层关联「830实验·共识」ALL PASS(`audit-5/6`),scan digest 含目录基线行(`audit-7`)。608 绿。存量 doc:/todo:/event:/file: 单文档源保留(关联即事元,静态引用)。 ## 24.10 AI推进|Dream 蓄水池落地 + scan 截断修复(2026-08-20,决策 33/34) **Dream 蓄水池(spec §17)**:`yzj_advance_dreampool` storage-domain(pool + meta 两表);Work scan 的每个 accepted 信号(IM + dir)copy 入池 pending,Work 即时处理不受影响。工具面:`yzj_advance_dream_status`(pending 清单+水位+lastDreamAt,description 内嵌抽取流程教学)+ `yzj_advance_dream_mark`(标记 done,host 内部状态不进 WRITE_SPECS)。服务面 `dreamState()` + RPC `advance-dream-state`。面板队列头水位行「池中 N 条待抽取 · 上次抽取 HH:mm」+「Dream 抽取」按钮(ask bus kind='dream',banner「Dream 抽取已预备」)。触发三径:手动(演示主路径)+ 水位提示 + 定时 schedule(沿用既有机制);host 自动唤起 agent 会话后置(迁移文档)。 **scan 截断修复**:830 实验观察项 3 落地——单页 20 条截断丢晚到信号;改 `listImMessagesAll` 自动翻页取完增量(`MAX_SCAN_MESSAGES=200` 防爆上限)。回归用例:基线后涌入 25 条 → 一次 scan 全收(25 条新信号)。 **验证**:单测 610 绿(+dream 水位行用例 +dir 全生命周期 +翻页回归);真机 `advance-dream-demo.mjs` ALL PASS:cursor 回拨→巡检入池→看板「池中 1 条待抽取」+「Dream 抽取」→banner 预备(`audit-8/9`)。明天演示路径=看板「巡检」→ 回看板看水位 → 「Dream 抽取」。 ## 24.11 AI推进|830 实验聚焦复验(2026-08-20,修复决策 25 + scan 截断后) 复验动机:决策 25(refs 去重收窄)与 scan 截断修复直接影响判定 3/4/5/8/9,原实验证据需在新代码下重取。方法:新探针事项「830 复验探针 0820」(A-20260820-001,不碰演示现场)重跑第 1 波四步;cursor 回拨 ANCHOR 重跑第 2 波。driver:`advance-830-reverify.mjs` / `advance-830-reverify2.mjs`。 | 判定 | 复验结果 | 证据 | |---|---|---| | 3 回放+目标更新弹卡 | **PASS(③ 一次成功)** | 部分重叠 refs(③ refs=[0812] ⊂ ② refs)不再被误吞,目标更新首试即落;`rv-replay3-card1.png` | | 4 队列头发现 N≥1 | **PASS(截断修复生效)** | 单轮 scan 取全 25 条(旧版单页 20 截断);17:18 工作现场、18:11 需求一等旧版丢失信号本轮可见 | | 5 信号命中 | **PASS** | 模型静默 feed 8 条真实 msgId refs(PRD/原型/评审/工作现场/需求一) | | 8 幂等 | **PASS** | 同 refs+changeType 重放 → 同源去重,事元不加行 | | 9 恰好 2 卡 | **PASS** | 立项卡 + 目标更新卡,全程 2 卡(原实验 3 卡的偏差消除) | | 6 噪音拒绝 | **漂移** | 原实验模型拒了竞争力报告;复验 run 模型把竞争力报告讨论聚合进 refs(作为「实质信号」之一)。同一信号集两次 run 判断不一致——判据教学面不够稳,见下 | **判据教学面修订提议(待拍板,§9.3 流程)**:`INSPECT_DISCIPLINE` 增补显式噪音例——「与事项目标/指标无显式引用的平行议题讨论(如战略竞争力报告评测线),即使高频出现也不作实质信号;只有显式引用本事项目标/指标/产物的消息才算信号」。理由:模型自由裁量下噪音边界漂移,需把 830 实验观察到的噪音类型固化进教学。拍板后改 spec §13.3 + `advance.ts` 教学字符串。 **复验暴露的非 bug 事实**:复验探针立项时未自动带线程①(driver 立项 prompt 未传 threads),首跑 scan 因「无订阅」全拒——订阅分发纪律(信号 ∈ 事项线程才 feed)按设计工作;手工关联 830 群后复跑即通。演示/真机立项走面板/话题路径时线程①自动挂(create threads 参数),不受影响。 ## 24.12 AI推进|概念修正:意图线程 → 上下文来源(2026-08-20,v1.8,全量改名含代码) 用户拍板:「意图」属于事项(意图体),渠道只是事项的**上下文来源**——旧命名把意图倒挂到了渠道上。改名深度:文档 + UI 文案 + 代码标识 + storage domain 全量改,含 legacy 存储迁移。 | 层 | 改动 | |---|---| | 代码标识 | `advance-threads.ts`→`advance-sources.ts`;`AdvanceThread*`→`ContextSource*`;`threadsOf/add/remove`→`sourcesOf/add/remove`;service `threadAdd/Remove`→`sourceAdd/Remove`;create 参数 `threads`→`sources`;RPC `advance-thread-add/remove`→`advance-source-add/remove`;detail 折叠字段 `contextSources`(与事元证据 `sources` 区分) | | 存储 | domain `yzj_advance_threads`→`yzj_advance_sources`(表 `sources`);`ContextSourceStore.open()` 时若新域空且 legacy 域有数据则一次性迁移(best-effort) | | UI | 右栏上区「订阅渠道」→「**上下文来源**」(入口「关联来源」),下区「当前判断来自哪里」→「**事元**」;testid `yzj-advance-source-*`;CSS `.subChip/.subSources` | | 文档 | spec §15 重写(持续源/静态源二分)+ 术语表/分期/决策 20 同步;migration 三概念加 v1.8 修订注记;README 索引同步;diagrams advance-1/6 重渲染 | | 历史节 | §24.5/§24.7 等历史留痕不重写(演进用追加段落,AGENTS.md 规矩) | **真机验证**:重启 GUI 后 830 事项「上下文来源」区显示迁移过来的两个订阅 chip(830 群 + 830实验·共识 目录)——legacy 迁移成功;下区「事元」正常。610 绿。截图 `shots-advance-ux/ux-redesign.png`。 ## 24.13 AI推进|巡检收敛:host 机械 routine,AI 只在抽取时出场(2026-08-20,v1.8,决策 35) 用户拍板:「巡检应该是不需要 AI 的,抽取事元才需要」。原混合双节奏(Work 模型实时判断 + Dream 再抽取)冗余且漂移(830 复验判定 6 观察到同一信号集模型两次判断不一致)。 | 层 | 改动 | |---|---| | host | `YzjAdvanceService.startPatrolTimer()`(setInterval ≥300s,ctx.effect 注册/卸载);tick = `patrolNow()` = coreScanAdvance 全量聚合入池,错误吞掉 | | 工具 | `yzj_advance_scan` 降级为只读查询(description 明示 host 巡检自动入池、抽取走 Dream);digest 不再附实时判断纪律;`INSPECT_DISCIPLINE` 删「巡检五步/订阅分发」改「抽取分发」 | | RPC | 新增 `advance-patrol-now`(面板「巡检」按钮 = 立即机械一轮,不切域不写 ask) | | 面板 | 水位达阈(DREAM_WATER_LEVEL=5)dreamState.waterLevelReached → 水位行「建议抽取」+ Dream 按钮高亮 primary | | 文档 | spec §14 重写(回路图/14.3 机械巡检);决策 34 水位 8→5、决策 35 入表 | **验证**:609 绿(巡检测例改机械断言:不切域/不写 ask/RPC 计数);typecheck 0。实时性 trade-off 记录于决策 35(偏差提示从实时变水位实时)。 ## 24.14 AI推进|存储切换:推进双表 dbt → local SQLite(2026-08-20,v1.8,决策 36) 云多维表格 record 服务间歇 500(code=10000506)全天多次:删探针重试 3+5+10 次全灭、830 数据无法导出。用户拍板 fallback:「如果还是有问题就把数据存储层换成 sql」。 | 层 | 改动 | |---|---| | 新增 | `advance-local-store.ts`:node:sqlite 双表(items/entries,fields 无损 JSON 中文键),singleton + `YZJ_ADVANCE_DB` 覆盖 | | 核心 | advance.ts 六触点(resolve/fetchItems/fetchItemById/fetchEntries/todaysEntryIds/writeTable)加 sqlite 分支;`setAdvanceBackend('sqlite')` 在 tool-yzj apply 启用;测试零改动(不 call 即 dbt) | | 数据 | 云导不出 → seed 脚本按实验记录重建 830 演示旅程(item + 5 事元,refs 用真实 docId);sqlite 写路径探针已删;上下文来源订阅(storage-domain)本就本地,原样在位 | | 验证 | 609 绿(dbt 测试路径不变);真机:空板 hero → 创建落库 → seed 后 830 看板完整(截图 sqlite-check/ux-redesign) | todo 家族仍留 dbt(用户未要求动);dbt 路径保留作测试与 legacy 回退。 ## 24.15 AI推进|todo + 缓存同切 SQLite,云 dbt 真机全死(2026-08-20,v1.8,决策 37) 用户拍板:「待办也切到 sqlite,云的直接干掉;消息列表之类的缓存也进 sql」。 | 层 | 改动 | |---|---| | todo | `todo.ts` 四触点(resolveLibrary/fetchTodos/fetchTodoByTodoId/writeRecords)加 sqlite 分支;`setTodoBackend('sqlite')` 真机启用;测试留 dbt double 零改动 | | 缓存 | `im-cache.ts`:localStorage L1 热备 + host SQLite L2 副本(scheduleSave 双写、loadPersisted L1 空时异步回填);host 新增 `im-cache-get/put` RPC(ui-yzj node half 直开同库) | | 存储 | 单库 `yzj_advance.db` 四表:items/entries/todos/im_cache | | 验证 | 609 绿;真机 todo 创建落库且列表可见(验收脚本 ux-sqlite-todo.mjs);im_cache 待真用户开群触发双写 | 云 dbt 残行(探针等)不再是任何路径的事实源;云服务恢复后可一次性物理清理。 ## 24.16 ui-yzj|推进「跳到消息」撞 home-fused 空 payload + overlay 跳转总线缺消费端(2026-08-20,pitfall-039) 用户报告:推进面板点「跳到消息」显示 `home-fused endpoint requires a groupId or sessionId payload` 且轮询刷屏。根因是 R27 overlay 空 占位 sessionId 与 slot 时代调用链叠加(详见 pitfall-039),连带 `requestImGroupFocus` 只有旧侧栏 panel 消费、overlay 时间轴 retarget 不了。 | 层 | 改动 | |---|---| | room-shell | binding fallback 仅 slot 模式(`yzj-home-*`)发起;新增 `subscribeImGroupFocus` 订阅(setActiveGroupId + rememberImSeat),推进跳转直达群 | | transcript | `YzjFusedView` viewKey 空时 load effect 短路(不 RPC 不轮询不 setError);空态文案「在左侧选择一个群开始。」 | | composer | speakers 轮询在 `sessionId === '' && groupId === ''` 时跳过 | | 验证 | 611 绿(room-shell 新增 2 用例:零调用断言 + imGroupFocus retarget);真机 verify-advance-jump.mjs 全 PASS(无报错空态 → 点群开房 → 推进 msg 来源跳转直达 im 域群房间 → 零 page error) | host 端 `stringField` 空=缺失校验保持原样(校验正确,错在 client 发空 payload)。Dream 抽取按钮的「跳群列表」体验断层属设计语义(askDraft 预备→话题问助手栏),见 ai-advance-design §14。 ## 24.17 ui-yzj|Dream 手动径重定义:host 直建会话一步到位 + 蓄水池面板可视化(2026-08-20,决策 38) 用户质疑决策 34 的 askDraft 两步形态:「不应该是跳转到新会话吗为啥是群里的话题助手」+「蓄水池没地方看有啥」。当时后置的「host 自动唤起会话」这轮补上——程序化建会话机制(话题同款)已验证。 | 层 | 改动 | |---|---| | host | bound-io 新增 `dreamAskPrompt()`(指令文本单一事实源迁 host)+ `runDreamSession()`(mint `yzj-dream-` → agents.create + followup 指令为 turn 1 → publishHostSession 钉标题「Dream 抽取 · 池中 N 条」);index.ts 新 RPC `advance-dream-run`(复用 topicAgentRoute/composition + attachYzjSession) | | 面板 | Dream 按钮 → `advanceDreamRun` → `focusBoundSession(sessionId)`(关工作台盖板 + 聚焦主会话);「池 N」按钮 → pending 明细浮层(dreamState 扩展 entries:id/channel/refId/content 前 120 字/sendTime) | | 清理 | advance-ask.ts 删 `dreamAskText`/`patrolAskText`(后者 v1.8 收敛后已是死代码);AskDraft.kind 收窄为 review/export;banner 文案删 dream/patrol 分支 | | 验证 | 613 绿(advance-pane 2 用例改写:RPC+聚焦+不再写 draft;bound-io 新增 runDreamSession);真机 verify-advance-dream.mjs 全 PASS(巡检入池 → 池浮层列 35 条 → 点抽取 → 盖板退下聚焦新会话「Dream 抽取 · 池中 35 条」→ 指令为 turn 1 → agent 开跑 dream_status → 零 page error) | `yzj-dream-*` 是普通 agent 会话(非 room/topic 视图),确认卡按 WRITE_SPECS 标准弹。旧 askDraft 机制保留给「请 AI 鎮收」「沉淀复盘」(绑事项、话题上下文有延续合理性)。 ## 24.18 AI推进|事元 msg ref 事件级定位:跳到消息而非只到群(2026-08-20,决策 39) 用户拍板:「跳转可以跳到 message 吗不是只是群;需要定位的是产生事元的事件」——三层模型(事件→事元→事项)与 spec 一致,实现欠账两点:msg ref 只存裸 msgId 不带群信息、跳转只到容器不定位消息。本轮补齐。 | 层 | 改动 | |---|---| | 工具面 | scan digest 信号行 `` → `:>`(模型原样抄入 refs);feed/create refs description 同步;dreamAskPrompt 教 agent 用池条目 channel+refId 组装 token | | 跳转总线 | `requestImGroupFocus` 升级为 `ImFocusTarget { groupId, anchorMsgId? }`(字符串兼容旧调用方);room-shell 消费 anchor 透传 YzjFusedView | | 时间轴 | `YzjFusedView` 新 `anchorMsgId` prop:viewKey 切换后 setHighlightMsgId → 既有高亮机制滚动+高亮该消息行;手选群清 anchor | | 面板 | 事元 refs chip 与来源列 msg 跳转接 `jumpToSourceMsg`:`im:g:m` 直达群+定位消息;legacy 裸 msgId 回退订阅渠道猜群 | | 兼容 | 存量事元裸 msgId refs 降级(跳群不定位);isRefReplay token 字符串比较不受影响(混格式漏判可接受);锚点不在首屏窗口时诚实降级(到群,自动翻页后续增强) | | 验证 | 616 绿(advance-pane 2 用例:anchor 直达/legacy 回退;room-shell 1 用例:scrollIntoView 落在锚点行);真机 verify-advance-anchor.mjs 全 PASS(seed `im::` 事元 → 点来源 → 直达 830 群 → 锚点消息行渲染 → 零 page error,seed 已清理) | **§24.18 续(同日)**:用户追问「不是有 sqlite 缓存吗,总得捞过吧」——核实后补齐最后一段:捞过的消息本体都在 bound log(每群 500 条持久,fused 全量读),锚点在 log 内的定位本就全覆盖;唯一缺口是从未开过的群只 backfill 最近 50 条。transcript 新增锚点自动翻页 effect(viewKey 级有界 10 页,复用 loadOlder;找到/到底/超界即停),room-shell 测试断言自动以最老一条为 beforeMsgId 翻页。真机 verify-advance-anchor.mjs 升级为窗外锚点(newest 20 + old 翻两页取 ~第 60 条)仍全 PASS。617 绿。 **§24.18 再续(同日,三层结构 UI 化)**:用户追问「三层结构为啥 UI 没跟着改」——refs 此前对用户是截断 ID chip,事件层不可读。补齐事件层呈现:host 新 RPC `advance-ref-lookup`(`im::` → bound log 命中的 谁/何时/说了什么),面板事元展开后 msg ref 命中渲染为可读事件行(点击仍定位消息,未命中降级旧 chip)。真机 verify-advance-anchor.mjs 事件行 PASS(`[08-20 17:06] 代少兵 …`);调试中发现并修复验收 seed 缺 `entry_id` fields 键被 parse 静默过滤的坑(pitfall-040,此前一轮「锚点 PASS」实为裸 msgId 事元的恰一群路径假阳性,本轮 seed 修复后锚点+事件行才是真验证)。618 绿。 **§24.18 三续(同日,纯三层树)**:用户再纠「右边是事元、事元下面是原始信息;多条信息→一个事元,多个事元→演进状态」——上一轮把聚合列改名为「原始信息」方向错了:扁平聚合列本身就破坏三层树(N:1 归属关系在 UI 上不可见)。本轮收掉扁平列:详情主体 = 推进演进(事元时间线,副标「多个事元折叠出演进」),事元展开见「原始信息 N」区(事件行可读化+点击定位),侧栏只留「上下文来源」订阅管理;sideNote 改写为三层结构自述。aggregateSources 升级 citing(引用事元列表)保留在 API 面(agent 仍可用);showAllSources 窗口化随列删除。测试:窗口化用例改为「聚合不再呈现」,msg 跳转用例改走事元展开路径;618 绿;真机 verify-advance-anchor.mjs(已改为事元展开→点原始信息行→跳转定位)全 PASS。 **§24.18 四续(同日,原始信息默认挂载)**:用户再纠「事元的列表怎么没了、原始信息放中间、这是 2 层」——上轮把原始信息藏进「展开详情」里,用户视角事元列表与原始信息的从属关系不可见(看着像两层)。改为默认挂载:每条事元行下直接渲染「原始信息 N」区(事件行/chip 默认可见,>2 条显示最新 2 条 + 「展开全部 N 条原始信息」;≤2 条且无 detail 时不再渲染 toggle)。三层一眼可见:事项→事元行→原始信息行。测试去掉展开前置步骤(默认可见);618 绿;真机 verify-advance-anchor.mjs 全 PASS;830 详情实测 11 个原始信息区默认可见(截图 4-tree.png)。 **§24.18 五续(同日,doc 叶子可读化)**:用户「你看看!我感觉不对」——界面结构渲染正常(11 个原始信息块、零错误),真正不对的是叶子:doc 类原始信息是截断 ID chip(文 6a85774a…),用户读不出文档是什么,三层看着像两层。advance-ref-lookup 升级为按 kind 解析(payload `{ refs: [{token,kind}] }`):msg → bound log 事件行(既有);doc → `doc get --id` 取 fileName(进程内缓存,miss 不缓存),面板命中渲染「文档 + 文件名」链接卡。真机 830 实测:4 个真实文档名全部显示(830纪要·0806/0812/0813…),截断 ID chip 清零;legacy 裸 msgId(Dream 抽取旧 digest 产物)仍降级 ID chip。619 绿。 **§24.18 六续(同日,事元描述默认展示)**:用户最终澄清「一个进度下面挂事元,事元本身也是一段描述,事元下面才是原始信息」——「事元」= 变化内容那段描述文字(此前折叠在「查看详情」里,视觉上进度行直接跳原始信息,描述层缺失)。改为 detail 默认渲染(entryDetail 样式,pre-wrap);toggle 收窄为仅 refList>2(「展开全部 N 条原始信息」)。四层呈现齐备:进度行(changeType·summary)→ 事元描述(detail)→ 原始信息(文档名/消息事件行)→ 点击直达现场。619 绿;真机 830 详情 3 段描述默认可见(截图 look-final)。 **§24.18 七续(同日,进度节点分组)**:用户「那进度更新不是从多个事元来的吗🤔」——此前时间线每行=一条事元,「进度更新」只是类型前缀,用户模型里的聚合层(进度节点=多个事元)缺失。呈现层改为两级树:连续同 changeType 的事元聚为一个「进度节点」(组头=类型+事元数+时间范围,如「进度更新 8 个事元 · 18:28 → 15:58」),节点内每条事元=summary+detail(描述)+原始信息,事元行不再带类型前缀。数据模型不动(纯呈现分组);真机 830 呈 6 个进度节点(备注1/进度更新2/目标更新1/进度更新8/偏差1…),完整四层:演进→进度节点→事元(描述)→原始信息。619 绿。