dsh-session-handoff
DSH 宿主插件(薄适配层):观测 → 阈值触发 → append-only 建议注入 → approval 门 → 调用 harness-automation CLI。
设计依据:docs/designs/session-handoff.md(v0.3,§5/§8/§9-P2);宿主能力查证:docs/spike-findings.md。
P1 实况校准:docs/designs/p1-delivered.md。验收记录:docs/acceptance-p2.md。
仓库:github.com/realpkuasule/dsh-session-handoff(镜像:github.com/xiaozhiaixue/dsh-session-handoff)。
本仓库带 dsh-plugin topic,供 DeepSeek Harness 插件生态发现。
边界(违反即返工)
- 只做观测、判定、触发。交接执行一律 spawn 全局
harness-automation session handoff,解析其 JSON 输出(ok字段),绝不复制任何交接逻辑。 - 注入只允许 append-only(
agent.inject()→ next-step inbox → 历史尾部追加,前缀不变)、确定性模板渲染(无时间戳/随机数)、状态不变时零追加(指纹去重,见下文)。 - approval 只在 open turn 内请求;无后台定时器;不单方面终止会话。
- 阈值只读策略文件(项目
.harness/session-workflow.yaml→ 包内默认),插件绝不改写;CLI 缺口只记录、不兜底。
装配(web profile)
标准方式(dsh plugin / bundle 机制):本包声明了 dsh.bundle.patch(cordis.patch.yml,按包名挂载
dsh-session-handoff 行)与插件清单 dsh.plugin.json。安装即挂载:
dsh plugin --profile web add dsh-session-handoff
# 或:dsh --profile web plugin add github:realpkuasule/dsh-session-handoff
本机当前即此形态:~/.dsh/profiles/web/package.json 的 link: 依赖 + dsh.profile.bundles 条目
(pnpm install 后由本包 cordis.patch.yml 提供挂载行)。
校验:dsh --profile web --dump-config(确认 dsh-session-handoff 行出现在组成树中);重启 web 生效
(python3 ~/DSH/dsh-sidechat/restart-dsh-web.py <当前pid> [delay-s],detached 安全重启)。
装配证据:pluginInventory/list 远程查询出现 dsh-session-handoff 且 phase=active。
开发快捷方式(可选):在 ~/.dsh/profiles/web/cordis.patch.yml 的 insert 列表加一行直接指向源码
(免安装、免 pnpm,但非标准分发形态):
- insert:
- id: dsh-session-handoff
name: 'file:///Users/zhichao/DSH/dsh-session-handoff/lib/index.js'
观测 → 判定 → 触发
| 阶段 | 实现 |
|---|---|
| 观测 | 投影单元 sessionHandoff(key,stateVersion 1,log-scoped 纯 fold:turns/steps/llmMs/titles/retries/splices/injected/cacheObs),注册于 ctx.sessionProjections;订阅 change feed (session, key, view, seq) |
| 判定 | computeCrossed(view, thresholds):turns ≥ 12、steps ≥ 150、llmMs ≥ 30min → 切换建议;titles ≥ 2 → 阶段漂移提示;retries ≥ 3 → 返工提示;splices ≥ 8 → 前缀缓存健康提示(默认值镜像 CLI 包内策略,项目策略文件可覆盖) |
| 触发 | 命中且未注入过的指纹 → 挂入 pending;该会话下一个 open turn(turn/start)注入一条确定性建议(微任务推迟,规避 session append cannot reenter) |
| approval 门 | 仅切换建议 + 工作项可得时,同 turn 内 ctx.approval.request();allowed-once → spawn CLI;rejected/cancelled/unavailable → 不动 |
| 执行 | harness-automation session handoff --project <cwd> --work-item <id> --session <id> [--dry-run];成功注入 seed 输出,失败只报告错误(CLI 缺口由负责人决策) |
工作项解析:工具参数 → session status 扫描(docs/HANDOFF-*.md → github:<owner>/<repo>#<issue>)。触发工具另可传 project 覆盖会话 cwd(跨项目触发)。--dry-run 默认 true(零写入)。
注入纪律与缓存观测(§5.4)
- 确定性渲染:消息内容只由
{signal, threshold, actual, projectPath, workItem, sessionId, dryRun}渲染,无时间戳/随机数;test/template.test.mjs断言两次渲染逐字节一致。 - 零重复追加:建议消息 id =
dsh-session-handoff-suggestion-<fp1>+<fp2>…(fp=signal:threshold)。注入前查agent.inbox.nextStep是否已有同 id;fold 从user/message事件读回指纹 →injected[],重启后 refold 依然去重(重启安全)。 - 前缀核对观测方法:fold 在注入建议后的第一个
assistant/message上记录cacheObs[] = {fingerprint, before, after},before=注入前最后一次请求的usage.cacheReadTokens,after=注入后第一次请求的usage.cacheReadTokens。前缀未受损 ⇔after ≥ before(新注入内容追加在保留历史之后,前缀逐字节不变)。日志侧证据:注入的user/message事件surfaceOp:"append"(见 spike-findings §3.1)。投影快照可直接读取:sessionProjections.snapshot(session).values.sessionHandoff.cacheObs。 - 自反馈防护:
splices计数排除source.plugin === 'dsh-session-handoff'的消息。
测试与验收(设计 §9 P2 对照)
test/replay.mjs:离线回放真实会话日志(session-3299f5d5、本会话),断言 fold 计数与日志事件逐项一致、两次回放逐字节一致。已验:session-3299f5d5 在默认阈值下 turns/steps/llmMs/titles/splices 五信号全部命中。test/template.test.mjs:阈值命中 → 模板确定性 → 指纹去重往返 → cacheObs before/after。10/10。- 装配验收:web profile 加载成功(pluginInventory phase=active);信号命中 → 下一 open turn 注入建议(live 观察);批准 → CLI 完成一次 handoff(dry-run 可接受;
allowed-once需会话 approval policy=ask);注入前后请求前缀对比(cacheObs + surfaceOp 证据)。 - 遗留与已知限制:
allowed-once路径在 policy=never 会话被确定性拒绝(seam 语义);验收时临时切 ask。- approval 答案若在 turn 结束后才落(用户长时间不点),
approval/decided审计事件可能非 turn-enclosed——宿主 seam 的已知行为(README "Only one-shot grants / requests valid only inside an open turn"),P3 可换用工具路径触发规避。 session/event是进程级投递:插件按 session id 过滤,每会话独立 fold/去重。- 项目策略文件的插件侧解析只认
thresholds:块标量数字键(无 YAML 依赖;CLI 权威解析 workflow.path 经session status复用)。
目录
lib/index.js 插件装配(feed/去重/注入/approval/CLI spawn/触发工具)
lib/projection.js 投影单元纯 fold(可离线回放)
lib/config.js 阈值策略读取(内置默认镜像 CLI 包内策略)
lib/template.js 确定性模板 + 指纹 + 命中判定
lib/cli.js harness-automation spawn 与 JSON 解析
test/replay.mjs 真实日志离线回放测试
test/template.test.mjs 合成事件测试
scripts/spike-analyze-log.mjs spike 离线分析工具
docs/spike-findings.md spike 结论
docs/designs/… 权威设计文档(只读)
No comments yet. Be the first to write one.