dsh-action-outbox:把 DSH 工具副作用放进可审查的持久化收件箱

前言

用 DeepSeek Harness(DSH)跑 agent 时,本地代码的改动可以靠 worktree 和文件检查点回滚,但 agent 对外部世界的写入没有对应的「撤销」:一条 issue 评论、一封邮件、一次部署或支付一旦发出,就收不回来。

DSH 背后的 Cordis 论文给这个边界指了两条路:把输出扣住直到 commit,或者为各领域定义补偿逻辑。dsh-action-outbox 实现的是前者——暂存期间不真正调用目标工具,人工审查批准后一次性提交,且不假装互不相关的外部系统共享一个原子事务。下面介绍这个插件的定位、用法和配置。

这是什么

dsh-action-outbox 是一个 DSH 插件,当前版本 0.3.0,MIT 许可证,由 JimchengChina 维护。一句话定位:DeepSeek Harness 工具副作用的持久化批量审查收件箱——暂存精确调用、检查或编辑完整 canonical JSON,批准后一次性提交不可变批次。

包本身是一个 DSH bundle,通过 cordis.patch.yml 自行激活。浏览器端只贡献官方 sidebar.footer.actionshell.overlay 两个插槽,不侵入其他 UI。

核心功能

  • DSH Web 侧边栏中的 Batch Review Inbox:展示完整参数、逐 action 字节数、工具来源、工具指纹、action hash,并支持复制与下载。
  • 暂存/编辑阶段零目标派发:只更新有界本地状态,不调用目标工具。
  • Review 重新解析实时 policy、工具身份、schema 与参数,返回 SHA-256 digest 加一次性 approval nonce;commit 只接受这一组合。
  • action_outbox_replace 可编辑已暂存的工具/参数/摘要,任何编辑都会使旧的 digest、nonce、review 与 approval 失效。
  • Fail-closed 长审查处理:被截断的批准卡片不能单独授权提交,必须显式确认完整 Inbox 视图。
  • 持久化待提交批次:状态文件权限为 0600;重启后草稿变为 needs_reapproval,须重新通过当前 policy/tool/schema 检查并获发新 nonce。
  • 崩溃安全提交恢复:提交中进程丢失转为 recovery_required;没有持久成功回执的 action 标记为 ambiguous,且绝不自动重试。
  • 内置 Copy safe demo prompt 引导路径;active/history 分离,过期批次不进入 pending 徽标,但保留证据,可查看或丢弃。
  • TOCTOU 防护与变更撤销:stage/unstage/replace 会清除所有先前 review、确认与 nonce;重启从不自动提交、从不复用 nonce。
  • 工具范围与参数可配:通过 include/exclude/enforce 通配符控制可暂存与强制走 outbox 的工具,另有 requireApprovalrejectDuplicateActionspersistPendingstateFilemaxPendingMsmaxActionsmaxArgumentBytesresultPreviewCharsapprovalPreviewChars 等配置项。

安装与启用

运行环境:engines 要求 Node ^22.19.0 || >=24.0.0;peer 依赖为 @deepseek-ai/dsh-tools >=0.1.0-rc.6 <0.2.0@deepseek-ai/schemastery ^3.18.1react ^18.2.0

推荐安装预构建 tarball,无需安装期构建权限:

curl -LO https://github.com/JimchengChina/dsh-action-outbox/releases/download/v0.3.0/dsh-action-outbox-0.3.0.tgz
npx @deepseek-ai/dsh plugin --profile web add ./dsh-action-outbox-0.3.0.tgz

也可以安装打了 tag 的 Git 源。Git 安装会执行包的 prepare 构建;pnpm 10 及以上需按 DSH 错误提示将 dsh-action-outbox 包键加入 profile 的 pnpm-workspace.yaml allowBuilds 后重试。固定 tag 可避免分支更新静默改变已安装代码:

dsh plugin --profile web add github:JimchengChina/dsh-action-outbox#v0.3.0

本地 checkout 同样可直接添加:

dsh plugin --profile web add ./dsh-action-outbox

首次运行建议走内置演示路径:打开 Outbox,点击 Copy safe demo prompt 并粘贴到一个新的 DSH 聊天。演示会在 /private/tmp 下暂存一次 no-clobber 文件写入,Review 后停止,不发起网络请求。

典型用法

Agent 侧的工作流固定为七个步骤:

1、action_outbox_begin({ label })
2、action_outbox_stage({ tool, arguments, summary? }),一或多次
3、可选:action_outbox_unstage({ action_id }) 或
   action_outbox_replace({ action_id, tool?, arguments?, summary? })
4、action_outbox_review()
5、在 Batch Review Inbox 检查完整批次;如批准卡片被截断,在 Inbox 中确认完整视图
6、Inbox 编辑后点击 Run fresh review;批次 reviewed 后按钮替换为
   Next: copy exact commit prompt,复制并粘贴到聊天提交
7、action_outbox_commit({ expected_digest, approval_nonce }) 或 action_outbox_discard()

有两点容易出错。其一,Inbox 里的 review 不进入聊天历史,不要只告诉 agent「用最新的 review」——模型可见的最新 review 可能是聊天历史里更早的 action_outbox_review 工具结果。要么粘贴 Inbox 给出的精确 commit prompt,要么让 agent 调用 action_outbox_review 并立即用该次调用返回的凭据提交。其二,commit 开始之前,discard 保证没有任何已暂存的目标 action 运行过;每次变更都会产生不同的授权状态,即使调用方仍持有旧的 digest 或 nonce。

配置

插件行为由 profile 中的配置项控制,下面是一个覆盖了主要选项的示例:

- id: action-outbox
  name: dsh-action-outbox
  config:
    include: ['github_*', 'slack_*', 'deploy_*']
    exclude: ['github_get_*', 'github_list_*']
    enforce: ['github_create_*', 'github_update_*', 'slack_send', 'deploy_*']
    requireApproval: true
    rejectDuplicateActions: true
    persistPending: true
    stateFile: ''
    maxPendingMs: 1800000
    maxActions: 20
    maxArgumentBytes: 65536
    resultPreviewChars: 2000
    approvalPreviewChars: 4000

各字段含义:

  • include:允许暂存的工具通配符模式。
  • exclude:对暂存与强制同时生效的例外。
  • enforce:拒绝直接调用、强制走 outbox 路由的工具模式,默认为空以保证兼容性。
  • requireApproval:对确切的 reviewed digest/nonce 要求一次批准;没有审批服务时 commit 会 fail closed。
  • rejectDuplicateActions:拒绝重复的「目标名 + 参数」组合,replace 也会被检查。
  • persistPending:持久化有界草稿与恢复回执,默认开启。
  • stateFile:可选的绝对或相对路径覆盖;为空时默认使用 $DSH_HOME/action-outbox/state.jsonDSH_HOME 未设置时为 ~/.dsh/action-outbox/state.json
  • maxPendingMs:未提交批次超过该毫秒数即过期;0 表示禁用过期。
  • maxActions / maxArgumentBytes:约束持久化状态的大小。
  • resultPreviewChars:约束面向模型的结果回执长度。
  • approvalPreviewChars:紧凑批准卡片的上限;超出时 commit 要求完整 Inbox 确认。没有 Inbox 的 headless/TUI 部署必须把它调高到能显示完整审查,否则会正确地 fail closed。

* 是唯一通配符,其他正则字符均按字面处理。

适用场景与注意

适合的场景:agent 需要向外部系统写入(评论、邮件、部署、支付等),希望在执行前有人审查完整批次;或者想把多个调用攒成一批、一次批准后按序经 DSH 工具管线派发。

使用前注意三点:

1、enforce 默认为空;requireApproval 开启且没有审批服务时,commit 会 fail closed,这是预期行为而非故障。
2、重启协议是单向的:reviewed 重启后变为 needs_reapproval,committing 中崩溃变为 recovery_required,未决调用标记为 ambiguous;重启从不自动提交、从不复用 nonce、绝不自动重试。
3、插件以当前 dsh 进程权限运行,安装前应检查源码与许可证(MIT)。

结尾

回顾一下这个插件的价值:它把「外部写入」从即发即收变成一条可审查、可撤销(提交前)、可恢复的批次流程——暂存零派发、digest 加一次性 nonce 授权、0600 状态文件持久化、崩溃后 recovery_required 且绝不盲目重试。如果你的 agent 会碰外部系统,值得把这条链路加进工作流。

插件目录页:https://www.skillhub.cn/plugins/JimchengChina/dsh-action-outbox (独立社区目录,与 DeepSeek / 幻方无官方从属关系);源码与 README:https://github.com/JimchengChina/dsh-action-outbox 。

羽毛球分组比赛记分
小程序二维码

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

Xiaoye