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 。

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

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

小夜