dsh-session-isolation:同一工作区多会话写入隔离

前言

DeepSeek Harness(DSH)里,每个会话在对话层是隔离的:各自有事件日志、agent 和上下文窗口。但多个会话往往共用同一个工作目录。在同一工作区并行开两个会话做不同事情时,agent 会按「这个目录就是我的项目」去写文件——改同一份索引、写同一路径,后写的整文件覆盖先写的,并不是会话隔离失效,而是多个写入方共享了同一批文件。

下面介绍社区插件 dsh-session-isolation(维护者 TOP1Wu,分类:工作流)。它为同一工作区里的每个会话划定写入边界:各自产出进独立目录,并在工具层拒绝覆盖仍由其他存活会话占用的文件。

这是什么

一句话:给同一工作区里的每个会话划一条写入边界。

DSH 生态里插件通过官方接缝扩展能力;社区目录是独立站点,与 DeepSeek / 幻方无官方从属关系。安装前建议自行查看源码与许可证——插件以当前 dsh 进程权限运行。

要解决的问题与装上之后的行为

典型冲突

README 描述的场景包括:会话 A 建目录级文档做索引,会话 B 在同一工作区把 B 项目内容写进同一份索引;并行时两路写同一路径,后者覆盖前者。

装上之后

  1. 每个会话(及其派生子代理)自动对应产出目录:<工作区>/.sessions/<会话短id>/
  2. 会话第一步会收到说明:工作区路径、本会话产出目录、写入边界(新文件写自己目录、不动别人文件、目录级索引默认不碰等)
  3. 当会话试图覆盖同一工作区里另一个仍存活会话已占用的文件时,write / edit 等文件工具在落地前被拒绝,并提示改写到自己的产出目录
  4. 归属会话结束或应用重启后自动放行,不会永久锁死文件

明确不做的能力

  • 不改变会话 cwd,是「约定 + 拒绝」式隔离,不是把进程 chroot 到子目录
  • 不拦截 bash 里的 >、tee、python -c "open(...,'w')" 等写文件方式
  • 若要物理级隔离,仍应「一个话题一个工作区」或使用 git worktree

核心机制

插件只依赖 DSH 扩展接缝,无第三方依赖,仅用 Node 内置 node: 模块。

机制 1:产出目录约定(agent/pre-step)

每个会话在第一步注入一次说明,包含工作区目录、本会话产出目录绝对路径,以及四条写入边界。子代理与父会话按血缘算作同一归属,可互相改产出;用户手动 fork 的会话是独立顶层归属。

机制 2:跨会话写入守卫(ctx.tools.guard)

在 write、edit、str_replace_editor、apply_patch 落地前检查目标路径:若文件已被同工作区另一存活顶层会话占用则拒绝;归属在 tools/result 里按「文件确实写到磁盘」记账,失败或被拒绝的调用不产生归属。

安装与启用

命令行 profile

插件为零第三方依赖,无需构建、无需联网。安装命令(README 原文):

dsh plugin --profile web add /绝对路径/dsh-session-isolation

装完后重启 DSH(CLI 安装不会热加载)。

DSH Desktop

桌面版真正的 DSH_HOME 为:

~/Library/Application Support/dsh-desktop/harness

不是 ~/.dsh。直接在终端跑 dsh plugin 会装进 ~/.dsh,对桌面版不生效。可用桌面内置插件市场,或显式指定 home:

DSH_HOME="$HOME/Library/Application Support/dsh-desktop/harness" \
  dsh plugin --profile web add /绝对路径/dsh-session-isolation

验证是否加载

dsh --profile web --dump-config | grep -A2 session-isolation

应能看到类似:

# == dsh-session-isolation
- id: session-isolation
  name: dsh-session-isolation

验证是否生效

重启后,在工作区开会话并让 agent 写文件,然后:

ls "<工作区>/.sessions"

应出现以会话短 id 命名的目录(短 id 为 $DSH_SESSION_ID 去掉 session- 前缀后的第一段)。

配置

全部通过环境变量:

变量 默认 作用
DSH_SESSION_ISOLATION guard guard = 约定 + 守卫;advise = 只注入约定、不拒绝;off = 完全关闭
DSH_SESSION_ISOLATION_DIR .sessions 产出目录名
DSH_SESSION_ISOLATION_MKDIR 1 设 0 则不主动创建产出目录,只告知路径

设为 advise 或 off 可在不卸载的情况下软化或关闭行为。

适用场景与注意

适合: 在同一工作区开多个并行会话、分别推进不同子任务,又暂时不想拆多个 clone 或 worktree 时,用约定 + 工具守卫降低互相覆盖的风险。

务必知晓的边界:

  1. 只拦文件类工具,不拦 bash 写文件;可靠解析 shell 困难,该路径仅靠机制 1 的约定
  2. 归属记录在进程内内存,DSH 重启后清空;已存在文件变为「无主」,谁先写入谁取得归属
  3. 不做物理隔离;强依赖 shell 或外部脚本大量写盘时,隔离不完整
  4. 仅顶层会话之间互斥;子代理并入父会话归属

维护者提供的离线测试:

node test/logic.test.mjs

README 称共 21 项测试,覆盖争用拦截、血缘归属、跨工作区不受影响、会话离线后放行等。

卸载

dsh plugin --profile web remove dsh-session-isolation

结尾

dsh-session-isolation 在 DSH「一切皆插件」的思路下,用 pre-step 约定和 tools guard 解决「多会话共享工作目录」带来的覆盖与混写问题。它不能替代「一话题一工作区」的硬隔离,但在工作流分类里,对同一目录多会话并行是可直接落地的折中。

  • 目录页:https://www.skillhub.cn/plugins/TOP1Wu/dsh-session-isolation
  • GitHub:https://github.com/TOP1Wu/dsh-session-isolation
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye