dsh-time-travel:为 DSH 工具副作用提供可逆回滚与审计

前言

在 DeepSeek Harness(DSH)这类「一切皆插件」的智能体运行时里,模型经常通过工具直接修改工作区:写入文件、编辑文件、删除文件,甚至执行 shell 命令或发起 HTTP 请求。这些副作用一旦发生,开发者通常缺少一个稳定的回滚入口:文件可能被覆盖,删除动作可能无法立即恢复,危险命令也难以事后追踪。

dsh-time-travelhelibeiqi 维护的 DSH 插件,MIT 许可。它的目标比较具体:给工具副作用建立「前状态快照 → 执行 → 补偿」链路,提供按轮次倒序恢复工作区的能力,并把命中审计规则的危险操作记录到审计日志中。

一句话定位

这是一个面向 DSH 插件系统的可逆时间旅行与审计插件:当 fs.writefs.deletebashhttp.request 等工具产生副作用时,插件尝试记录前状态并注册补偿动作,随后通过 ctx.timeTravel.rewindTo(turnId) 按轮次恢复工作区,同时内置审计规则引擎记录危险操作。

仓库信息:

name: dsh-time-travel
owner: helibeiqi
license: MIT
package.json version: 0.2.0
engines: node >=18

核心功能

下面介绍几个可核实的能力。

监听工具管线事件

插件监听 DSH 的工具管线事件:

tools/pre-execute
tools/result

它围绕四类工具建立快照与补偿链路:

fs.write
fs.delete
bash
http.request

其中,文件类工具更适合做自动补偿;shell 和 HTTP 请求类工具通常难以自动逆转,插件会走审计或人工处理路径。

按轮次回滚工作区

插件提供 ctx.timeTravel.rewindTo(turnId)。调用后,它会按轮次倒序执行补偿,尝试恢复工作区到指定轮次之前。

例如:

const report = await ctx.timeTravel.rewindTo('T3')

这一行的含义是:撤销 T3 及之后所有可补偿的工具副作用,并返回一份回滚报告。

提供一组运行时 API

插件挂载后,运行时上下文会暴露 ctx.timeTravel,可使用的能力包括:

rewindTo
rewindAll
records
clear

其中:

  • rewindTo(turnId):回滚到指定轮次之前;
  • rewindAll():执行全部可补偿回滚;
  • records(sessionId):查看工具副作用记录;
  • clear():清理记录。

示例:

const records = ctx.timeTravel.records('session-abc123')

await ctx.timeTravel.rewindAll()

内置审计规则引擎

插件内置审计规则引擎。当操作命中危险 shell、敏感路径写、不可补偿写操作等规则时,会追加一行 JSON 到审计日志。

默认审计日志路径为:

audit-log.jsonl

该路径可通过 audit.logPath 配置。

审计日志使用 JSON Lines 格式,每条记录是一行 JSON,便于后续接入日志系统或做人工复核。

失败隔离

插件副作用通过 ctx.on() 注册。插件卸载时会自动撤销这些副作用。

同时,插件设计目标之一是:快照或审计失败不应影响工具本身执行。也就是说,回滚与审计是附加链路,不应阻塞正常的工具调用。

安装与启用

在插件工程根目录执行:

dsh plugin --profile web add /absolute/path/to/dsh-time-travel

这里的 /absolute/path/to/dsh-time-travel 需要替换为本地仓库绝对路径。

如果手动打包安装,README 给出的等价路径是先执行 npm pack,再在 profile 目录安装生成的 tgz 包。示例中使用的是:

npm pack

然后:

cd ~/.dsh/profiles/web
npm install /absolute/path/to/dsh-time-travel-0.1.0.tgz --no-save --no-audit --no-fund

安装后,需要重启 dsh web 使插件生效,默认端口为:

3080

典型用法

下面的示例用于展示插件挂载后的编程调用方式。

import { Context } from '@deepseek-ai/cordis'
import { apply } from 'dsh-time-travel'

// 插件被 dsh 加载后,apply 已执行;以下仅为编程调用示例
const ctx: Context = /* dsh 注入的根 Context */

// 模型调用 write 覆盖了 a.txt 之后:
const report = await ctx.timeTravel.rewindTo('T3')
// 撤销 T3 及之后所有工具副作用

// 查看当前记录(可按会话过滤)
const records = ctx.timeTravel.records('session-abc123')

// 全部回退
await ctx.timeTravel.rewindAll()

使用顺序通常可以这样理解:

1、插件加载后,ctx.timeTravel 可用;

2、工具执行过程中,插件记录副作用并准备补偿动作;

3、当确认某轮次开始的操作需要撤销时,调用 rewindTo(turnId)

4、如果需要查看所有待回滚或已记录的工具副作用,调用 records(sessionId)

5、如果确认全部回滚,调用 rewindAll()

配置项

已核实的配置项包括:

audit.logPath

审计日志输出路径,默认值为:

audit-log.jsonl

日志格式为 JSON Lines,相对当前工作目录解析。

dryRun

类型为布尔值。当 dryRuntrue 时,rewind 只输出报告,不实际执行补偿。

适合在排查问题时使用:先确认哪些副作用会被回滚、哪些会被跳过,再决定是否真正执行补偿。

maxRecords

用于控制内存中保留的最大工具记录数,默认值为:

10000

超出上限后,最旧记录会被丢弃。审计日志写入不受该内存记录限制影响。

可自动补偿与仅审计的工具

默认映射中,文件类工具更容易做自动补偿:

write / edit:可恢复原内容或删除新建文件
delete:可写回原内容

而以下工具通常不可自动补偿:

bash
pwsh
http.request

这些工具命中审计规则后,插件以审计留痕或 manual 提示为主,交由人工判断。

这一点在实际使用时比较重要:不要把 rewindTo 理解成“所有副作用都能一键撤销”。它能恢复的是可补偿的文件系统状态;对于 shell 执行结果、外部 HTTP 请求等已经离开本地工作区的动作,插件不会冒险自动猜测回滚方式。

兼容性与安装注意

插件兼容:

DSH 0.1.0-rc.6
cordis 4.x
schemastery 3.x

安装时应以本仓库版本为准,不建议直接裸装 @latest

插件会在当前 dsh 进程权限下运行,并且会读取工具调用、写入审计日志,部分场景下还会尝试恢复文件。安装前建议先检查源码、依赖与 MIT 许可证,确认它符合当前环境的权限边界。

适用场景

这个插件适合以下几类场景:

  • dsh web profile 中运行工具密集型智能体,需要快速恢复工作区文件;
  • 想对 writeeditdelete 等文件工具建立可回滚链路;
  • 需要对危险 shell、敏感路径写入、不可补偿写操作留下审计痕迹;
  • 希望在插件卸载后自动撤销监听器,避免污染 DSH 工具管线。

它主要处理的是工作区文件副作用的回滚与审计。会话消息层面的回退、会话事件日志重放,不在这个插件的职责范围内。

结尾

dsh-time-travel 的价值在于把工具副作用从“执行后只能人工排查”变成“可记录、可回滚、可审计”。它通过 ctx.timeTravel 提供按轮次回滚能力,通过审计日志保留危险操作痕迹,并通过 ctx.on() 注册副作用,保证插件卸载时可以自动撤销。

仓库地址:

https://github.com/helibeiqi/dsh-time-travel.git
羽毛球分组比赛记分
小程序二维码

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

Xiaoye