# DSH 唯一会话家园:会话对象与产品法 > **v2.0 覆盖(2026-08-17,Guoxin Shan)**:[`group-room-topics.md`](group-room-topics.md) 取代本文的会话基数与视图模型——D2(1:1 绑定)、D3(四类节点一条流)作废,D5/D6 改写;D1/D4/D7–D11 保留。**D8「丢进群」UI 已于 2026-08-27 退役(决策 55)**。保留/作废逐条对照见该文 §6 / §12。本文 v1.x 正文不改写,作历史快照;新实现以 v2.0 为准。 > 版本:v1.0(已拍板)+ **第一刀已落地**(绑定对象,2026-08-16)+ **第二刀已落地**(融合时间线 / composer 双意图 / 丢进群 / 面板降级,2026-08-16)+ **v1.1 文案**(2026-08-16):产品手势是云之家 @机器人、DSH「发给助手」;说话人「助手」。Claude Tag / @Claude 仅作对照类比,不是产品名。D1–D11 实质不变。——对照见 [`../status/gap-analysis.md`](../status/gap-analysis.md) §22。G3(确认卡 pending 仍非 session 事件)、G5(群搜索)仍开放。 > 日期:2026-08-16 > 决策人:Guoxin Shan > 定位:产品法 + 会话对象契约。整体方案只加 v1.8 指针([`integration-master-plan.md`](integration-master-plan.md));机器人协议仍见 [`robot-channel-plan.md`](robot-channel-plan.md),其隐藏平行 session / fork 开新根在本法规下作废。 > 文档形态:**独立 spec**,不塞进总方案——总方案已覆盖工具/面板/旅程/分期,再塞会话对象会不可读。 > 下一片(绑定后的**可见时间线**:①② 插件消息日志 × ③④ 官方事件融合):[`dsh-home-transcript.md`](dsh-home-transcript.md)。本文 D1–D11 不变。 --- ## 0. 北极星 **DSH 是唯一的对话家园。云之家消息是这条 DSH transcript 里的一等公民,不是侧车 IM。** 云之家仍是投递面与引用源(群里能看见、能 @、能回源),但**对话发生在 DSH 会话里**。不存在第二套聊天窗、第三套机器人会话作为产品家园。 现行实现:**绑定表已落地**(`ctx.yzjHome`,storage-domain `yzj_home_bindings`);**消息日志已落地**(`yzj_home_logs`,按 `yzjConversationId`);入站 `followup()` 与面板挑群打同一条 `yzj-home-*` 会话;绑定会话 `conversation.view`「群工作」融合 ①②③④;composer 双意图;丢进群默认摘要 + 确认模态。面板 IM composer 降为快捷发进群(写 ②),不是第二家园。G3/G5 仍开放。 --- ## 1. 决策表 | # | 决策 | 结论 | 理由 | |---|---|---|---| | D1 | 对话家园落点 | **DSH 会话是唯一家园**;云之家消息进该 transcript,不是侧车 IM | 三面并行(DSH / 面板 / 机器人 session)让同一段群工作出现三次、身份分裂;用户要的是一条流里同时看到群消息、自己发进群的话、对 agent 的话、agent 的话 | | D2 | 绑定基数 | **一条云之家会话(群或 DM)↔ 恰好一条 DSH session** | 「打开一个群」= 切到该绑定会话,不是再开一个聊天;入站 `followup()` 也进这条,否则群工作在隐藏 session 里,DSH 列表里看不见 | | D3 | 流内节点 | **四类节点共一条流**(§3):入站云之家消息;用户以本人身份发进群(无确认卡);用户对 agent 的轮次;agent 轮次(agent 提议发群仍走确认卡) | 侧车面板只有前两类、DSH 只有后两类,拼不出「群工作在 DSH 里发生」;机器人出站不是第五类说话人 | | D4 | 机器人身份 | 机器人在云之家的帖子 = **本会话 agent 轮次的投递**,不是产品模型里的第三说话人 | 群里看见的是同一个助手;DSH 里也是同一个。另开 `yzj-robot-*` 说话人会让「谁在回」无法指认 | | D5 | 面板角色 | **挑选器 / 历史 / 额外引用面**。无第二套 IM composer。「挑群」打开或切换绑定会话 | 面板 composer 是第二家园。挑群的目的是进入那条 DSH 会话,不是在浮层里另聊一套 | | D6 | 群面召唤 | 绑定群会话里,**@机器人是召唤手势**。每群一个共享 agent 身份;工作在同一条线程可见;任何人可续 | 这是绑定会话的群脸,不是第三家园。对照/类比:对齐 Claude Tag 的「频道里 @」(仅对照,不是产品名),但会话单位是**整群绑定**,不是每条回复链一个 DSH session | | D7 | 未绑定会话 | **未绑定 DSH session = 经典 1:1 agent 私聊**。无群 IM 流、无共享 @机器人召唤、单一发送按钮。仍可拉入云之家引用 | 私聊与群工作必须可分;默认不是群。绑定是显式动作(挑群,或「丢进群」) | | D8 | 丢进群 | **一等交接**:私聊 → 绑定群会话。默认分享**可见摘要**(用户勾选的结论/引用),私聊 transcript 仍私密。**全文迁移**(整段历史变群可见)须显式、罕见。**发进群前确认卡**。交接后落在绑定群会话,助手以群共享身份续 | 私聊里想好的东西要进群协作,但不能默认泄密;确认卡守住「一旦发出即群可见」 | | D9 | 写路径 | **用户从 DSH 发出(含现行面板 composer 的过渡态)= 用户意志,无确认卡。agent 发起的发送 = 确认卡。删除类 = 强确认。确认卡不跟 GUI 权限档位走:Full access 仍弹云之家写确认卡** | 把 v1.7「待拍板」成文。用户自己点发送不是 agent 代发;闸门只拦 agent。删除不可逆故强确认。Full access 只放开本机文件沙箱(`approval=never` 是给 bash/fs 免确认用的);发消息/删文档是云上副作用,走 `yzj/confirm-request` 自托管,不 return harness `ask`(pitfall-036) | | D10 | 隐藏平行 session | **`yzj-robot-*` 隐藏会话、以及 `!fork` / `robot_fork` 开新根,在本法下错误**——应打开或恢复绑定会话 | 它们把群工作藏进第二条根会话,违反 D1/D2。协议层仍可 `followup()`,目标必须是绑定对象,不是平行根 | | D11 | 免 @ / ambient | **本版 MVP 不做**。顶层无 @ 的群消息不自动进 agent;「按判断响应」与频道 ambient session 留后期 | 云之家协议默认只投递 @ 机器人;未验证的免 @ 会误触发。召唤手势先做对 | --- ## 2. 会话对象 只读 `docs/` 的下一个 agent 必须能凭本节重建对象,而不是从实现反推。 ### 2.1 形态 ``` DshHomeSession dshSessionId: string // harness live session,唯一家园 id binding: | { kind: 'unbound' } | { kind: 'bound' yzjConversationId: string // 云之家 groupId(群或 DM,与 CLI 同 ID 空间) yzjKind: 'group' | 'dm' } ``` 不变量: 1. **绑定基数 1:1**。任意 `yzjConversationId` 至多对应一条 `dshSessionId`;一条 `dshSessionId` 至多绑定一个云之家会话。 2. **打开即切换**。挑群 / 打开已绑定群 = `focus(boundSession)`,禁止再 `create()` 一条平行聊天。 3. **入站进绑定**。机器人入站 `followup()` 的目标 = 该 `yzjConversationId` 的绑定会话;无绑定则创建并绑定,然后 `followup()`。禁止再分配 `yzj-robot--` 这类平行 id 当家园。 4. **未绑定无群流**。`kind: 'unbound'` 不渲染入站云之家消息,不出现「以本人身份发进群」,发送按钮只有「对 agent」。 5. **绑定有群流**。`kind: 'bound'` 的 transcript 含 §3 四类节点;composer 同时承担「对 agent」与「以本人身份发进群」(产品模型里是两种意图,chrome 可以是双按钮或模式切换,但**不得**把「发进群」放到面板第二 composer)。 ### 2.2 生命周期 | 动作 | 结果 | |---|---| | 新建 DSH 对话(默认) | `unbound` 私聊 | | 挑群(面板或 @群)且该群尚无绑定 | 创建(或复用空闲)DSH session,写入 `bound`,focus | | 挑群且绑定已存在 | 只 focus 已有 session | | 云之家侧 @ 机器人(群或 DM) | 打开或恢复该会话的绑定 session,`followup()` 进它 | | 丢进群(§7) | 目标群按上两行打开/恢复;摘要(或显式全文)经确认卡发进群;用户 focus 到绑定会话 | | 解绑(后期,非 MVP) | 可选:绑定解除后该 DSH session 变回 unbound;群侧历史不删。本版不规定 UI | 持久化:绑定表是产品对象,不是路由缓存。重启后「这个群对应哪条 DSH 会话」必须仍是同一条。实现可落 storage-domain,但语义是会话对象的一部分,不是机器人包的私有 `lastSession` 线索。 ### 2.3 明确拒绝的旧对象 | 旧对象(现行实现) | 本法 | |---|---| | `yzj-robot--` 作为持久家园 | ❌ 隐藏平行 session | | 群内每条回复链一个新 DSH session(robot-channel-plan S1「顶层 @ → 开新 session」) | ❌ 违反 1:1;链内引用是 transcript 内的回复关系,不是新家园 | | 每群一个额外 ambient DSH session | ❌ 本版不做 ambient;routines 投递进**该群的绑定会话**(仍是同一条),不是第二条 | | `robot_fork` / `!fork` 产出 `fork-yzj-robot-…` 新根 | ❌ 应 `focus` 目标群的绑定会话;跨群交接走 §7「丢进群」语义(摘要 + 确认卡),不是 fork 出第三条根 | | 面板会话 tab 的独立 IM transcript | ❌ 那是侧车;绑定后的家园 transcript 在 DSH | 协议层(WS 入站、ack-then-push、sendMsgUrl、allowFrom)仍以 [`robot-channel-plan.md`](robot-channel-plan.md) 为准;**改的是 session 落点,不是通道**。 --- ## 3. 四类节点,一条流 绑定会话的 DSH transcript 按时间交错包含四类节点。未绑定会话只有 ③④(外加可拖入的引用 chip,引用不是节点类型)。 | # | 节点 | 谁产生 | 确认卡 | 云之家侧可见 | |---|---|---|---|---| | ① | **入站云之家消息** | 群/DM 里他人(或自己在云之家客户端发的)经 CLI/机器人入站投影进 DSH | 无 | 已在云之家 | | ② | **用户以本人身份发进群** | 用户在 **DSH 绑定会话**点发送(过渡期:现行面板 composer 同等语义) | **无**(用户意志) | 是,用户本人身份(CLI `im message send`) | | ③ | **用户对 agent** | 用户在 DSH 对助手说话 | 无 | 否(除非用户随后把内容 ② 发出或授权 agent 发) | | ④ | **agent 轮次** | 助手在本会话的回复 / 工具 / 确认卡 | agent **提议发进群** → 标准确认;删除类 → 强确认 | 仅当该轮次被投递:机器人帖子 = ④ 的投递,不是第五说话人 | 渲染要求(验收口径,非实现处方): - ①② 看起来像 IM 气泡(发送人、时间、群内回复关系),但**住在 DSH 会话**,不是面板里另一份日志。 - ③④ 保持 DSH 对话既有形态(用户轮 / assistant / 工具卡)。 - ④ 若已投递到群,终态标记「已投递到群」(deep link 可回云之家或面板锚点),不另开「机器人说:」身份。 - 确认卡是 ④ 的挂起态,必须出现在**这条**会话流里(见 gap:现行 pending 不进 session 日志,是阻塞项)。 --- ## 4. 面板角色 悬浮球工作台仍是云之家的**浏览与引用面**,不再是第二聊天窗。 | 做 | 不做 | |---|---| | 挑群 / 翻历史 / 未读入口 | **第二套 IM composer**(绑定会话的发送在 DSH) | | 「挑群」→ 打开或切换绑定 DSH session | 在面板里把一段群聊聊完 | | 知识库 / 日程 / 待办浏览;条目拖进 **DSH composer** 成引用 chip | 把面板消息流当作家园 transcript | | 设置 → 云之家(机器人通道、记忆库) | 用机器人 tab 当第三套对话 | 过渡期:现行面板 composer 仍按 D9 视为用户意志(无确认卡)。目标是**移除或降级**——降级若保留,只允许作为「发进当前绑定群」的快捷入口,且必须写入绑定会话的 ② 节点,不得只写面板缓存。 --- ## 5. 群面:Claude Tag(召唤,不是第三家园) 本节标题「Claude Tag」是对照/类比,**不是产品名**。产品手势:云之家 @机器人;DSH「发给助手」。对齐 Claude Tag(仅对照)的频道召唤。 绑定**群**会话时,群脸对照 Claude Tag 的「在频道里 @」,但家园是 DSH 绑定会话: - **召唤**:云之家侧 `@机器人` 把该消息作为 ① 进入绑定会话,并触发 agent 轮次 ④。 - **共享身份**:每群一个助手,不是「发起人的私有 bot」。群成员在同一条线程里看见工作;任何人可续(白名单 `allowFrom` 仍是安全闸,不是身份分裂)。 - **可见性**:④ 投递回群后,群线程与 DSH transcript 描述的是同一段工作。 - **不是第三家园**:不要为 @机器人 另开 `yzj-robot-*` 或 per-thread DSH session。回复链是节点上的引用关系(`replyMsgId`),用来续写同一条绑定会话,不用来 `create()` 新根。 未绑定私聊没有这张群脸(D7)。免 @ / ambient 见 D11,非本版。 --- ## 6. 私聊面:未绑定会话 未绑定 = 用户与助手的经典 1:1: - 无 ①② 群 IM 流; - 无共享 @机器人召唤(云之家群召唤进的是绑定会话,不是这条私聊); - **单一发送按钮**(只对 agent); - 仍可用 @ / 拖拽把云之家群、消息、文档等**当引用**拉进来(既有 chip / codec,引用 ≠ 绑定)。 后期可选:把一条私聊**绑定到某群**(变成绑定会话)。本版用 §7「丢进群」完成「私聊成果进入群工作」;是否保留原 session 为 unbound、另开绑定会话,由交接实现选定,但用户着陆点必须是绑定群会话。 --- ## 7. 丢进群 从**未绑定私聊**把工作交到**绑定群会话**的一等动作(产品名「丢进群」)。 | 项 | 规则 | |---|---| | 默认载荷 | 用户勾选的结论 / 引用做成**可见摘要**发进群;私聊全文仍私密 | | 全文迁移 | 整段私聊历史变为群可见——**显式、罕见**,不得当默认 | | 闸门 | **任何内容发进群之前确认卡**(标准确认;用户能看到将发出的摘要或「全文」范围) | | 着陆 | 确认后用户 focus 到该群的绑定会话;助手以该群共享身份续,不带着私聊人格平行说话 | | 与 `!fork` / `robot_fork` | 旧命令若保留,语义改为「打开/恢复目标群绑定会话 + 可选摘要交接」,**禁止** `agents.create` 新根 | 跨群交接(A 群绑定会话 → B 群绑定会话)同一套:摘要默认、全文显式、确认卡、着陆目标绑定会话。 --- ## 8. 写路径(D9 成文) 把总方案 v1.7 §5.5「待拍板」、根 README「待正式拍板成文」、todo §11.2 决策 5 收成同一条法。**闸门看发起者,不看通道。** | 发起者 | 动作 | 确认 | |---|---|---| | 用户 | 在 DSH 绑定会话以本人身份发进群(②);过渡期面板 composer 同等;`/yzj` `home-send` / `im-send` | **无** | | 用户 | 面板其它直操作(待办勾选/新建、记忆「记一条」、共享区打开等既有直写) | **无** | | Agent | 提议 `yzj_im_message_send` 等写工具(含「代发进群」) | **标准确认** | | Agent | 在绑定家园调用 `robot_notify` / `robot_continue`(机器人身份推群) | **标准确认**(与 IM 写同闸;未绑定操作者控制台与面板 RPC 仍无卡) | | Agent | 删除类写工具 | **强确认** | | 机器人通道 | 把已放行的 ④ 投递到云之家 | 不再弹第二张卡;投递不是新的写发起 | 无人值守(routines / chatnode)产出进入**该群绑定会话**的 ④,再投递。它不是第三说话人,也不是第三条写路径;若该产出本身是写工具,仍按 Agent 行走确认(群内建议卡或 GUI 卡,看用户当时在哪面操作——产品上仍是同一 writeId)。 --- ## 9. 与既有设计的关系(不重写历史) | 文档 | 关系 | |---|---| | [`integration-master-plan.md`](integration-master-plan.md) v1.7 及更早 | 人在闭环、确认卡、面板、拖拽仍成立。v1.8 **追加指针**,不改写 v1.1「机器人=下期」原文;该判断已被通道落地 + 本法取代 | | [`robot-channel-plan.md`](robot-channel-plan.md) §3.6 S1/S3/`robot_fork` | 协议与 Claude Tag 对齐调研保留(仅对照,不是产品名)。v0.2 **追加**:隐藏平行 session 与 fork 开新根在本法下作废,入站改打绑定对象 | | 待办设计(已归档) | 用户直写原则与 D9 一致;待办页签已从公开仓撤出(2026-08-27) | | 根 README / AGENTS.md | 写路径两分改为已拍板;并指向本文为会话对象事实源 | --- ## 10. 验收口径(实现对照用) 只读 docs 的评审应能回答:家园在哪、绑定是什么、四类节点、面板是否还是 IM、@机器人 进哪条 session、丢进群默认是否泄密、谁弹确认卡。实现完成时至少: 1. 打开群 A 两次,DSH 会话列表仍只有一条绑定会话,第二次是切换。 2. 群 A 里 @机器人,followup 进该绑定会话,不出现新的 `yzj-robot-*` 家园。 3. 绑定会话 transcript 同时能看到入站群消息、用户本人发出的群消息、发给助手的话、助手的话。 4. 用户从 DSH 发进群不弹确认卡;助手提议「发进群」弹确认卡;删除类强确认。GUI「Full access」档位下云之家写确认卡仍弹出(不因 `approval=never` 自动拒绝)。 5. 面板挑群会切 DSH 会话;面板没有(或不再作为)独立 IM 输入作为家园。 6. 未绑定会话只有对 agent 的单一发送,无群流。 7. 「丢进群」默认摘要 + 确认卡;全文迁移需显式;完成后 focus 绑定群会话。 8. `!fork` / `robot_fork` 不再 `create` 新根(或文档与 UI 标明已废止)。 阻塞缺口清单以 gap-analysis §22 为准。**已关闭**验收 1、2、3(群工作融合流)、4(发进群落点在绑定 composer / 面板快捷写 ②)、5(面板降为快捷入口)、6(未绑定单一发送 + 丢进群)、7(丢进群默认摘要 + 确认)、8(`!fork`)。仍开放:G3(pending 非 session 事件)、G5(群搜索)。 --- ## 11. 本版明确不做 - 免 @ / ambient / 「按判断响应」顶层群消息(D11)。 - 解绑 UI、一条 DSH session 绑多个群、多个 DSH session 绑同一群。 - 把云之家客户端变成 DSH 的皮肤(云之家仍是投递面)。 - 改 harness 才能做的确认卡事件族——列为 §22 阻塞项,不在本文发明旁路协议。