前言¶
在 DeepSeek Harness(DSH)裏,會話權限可以選「自動審批」(預設 auto)。不少開發者會長期用這個檔位,希望 Agent 在可控範圍內自動過審。實際使用中有一個現象:選過 auto 後正常退出 DSH,再打開同一會話,權限卻變成了「完全權限」(danger-full-access,審批策略 never)。這不是偏好沒保存,而是退出流程裏有一次向更高權限的持久寫入。若 DSH 版本仍帶未修復的上游邏輯,每次關應用都會重演。本文介紹社區插件 dsh-auto-preset-guard(維護者 SternChiri,分類 admin-security),說明它針對什麼問題、如何安裝,以及和上游修復的關係。
這是什麼¶
dsh-auto-preset-guard 是一條常駐的 DSH host 插件行:在運行期包裹 permissionPresets 服務,不修改安裝目錄裏的任何包,升級 DSH 不會把改動覆蓋掉。
它解決兩類與 @deepseek-ai/dsh-experimental-auto-review 相關的副作用:
- 應用退出時,集成在 effect disposer 裏會把當前仍是
auto的會話批量set成danger-full-access;set()會往會話日誌追加事件,因此重啓後看到的是被改寫後的權限。 - 會話日誌裏存着
auto、但自動審批集成未激活時,pinInitialPermission可能拋出permission: cannot restore preset "auto" without its active integration,會話無法重新打開。
上游已在提交 4923f3cb(「fix(auto-review): preserve Auto during application shutdown」)中通過判斷 ctx.root.fiber.state 區分「應用退出」與「運行中卸載插件」;該修復從 0.2.2-alpha.2 起進入主線,0.2.1-rc.* 仍可能執行無條件的遷移循環。本插件面向尚未升級或仍需兜底的環境。
背景:退出時爲何會升到完全權限¶
auto-review 在 disposer 中的邏輯大致如下(摘自倉庫說明):
for (const session of ctx.sessions.list()) {
if (permissionPresets.current(session) !== AUTO_PRESET) continue
permissionPresets.set(session, 'danger-full-access')
}
設計意圖是:運行中卸載自動審批集成時,把仍停留在 auto 的會話遷到完全權限,避免留下無法服務的預設。同一 disposer 在應用退出時也會執行,而退出時本應保留用戶選擇。cordis 的卸載順序是 root 先進入 UNLOADING,再跑子插件 disposer;因此在 disposer 階段讀取 root fiber 狀態,可以區分「正在關應用」與「root 仍爲 ACTIVE 的活體卸載」。未修復版本無法區分,導致每次退出都寫入遷移。
核心功能¶
插件只做兩件事,且僅在服務實例上安裝一次包裹(Symbol.for 標記);dispose 時故意不解包,避免在本行先於 auto-review 卸載時把原方法還原、讓關機遷移重新生效。
| 行爲 | 說明 |
|---|---|
關機窗口內忽略 set(session, 'danger-full-access') |
當 root fiber 不是 ACTIVE(如 PENDING、LOADING、FAILED、DISPOSED、UNLOADING),且會話當前預設爲 auto 時,不寫入會話日誌 |
放寬 pinInitialPermission 對「auto 缺集成」的處理 |
會話按存儲身份正常打開,不爲此追加降級事件 |
運行中卸載 auto-review 時 root 仍爲 ACTIVE,上游遷移仍會執行——插件不干預這一路徑。若宿主無法識別(root.fiber.state 不是數字),所有調用保持原樣。
安裝與啓用¶
npm 上的 0.1.0 與 GitHub main 上 v0.1.0 tag 等價。要求 Node ^22.19 || >=24,DSH >=0.2.0 <0.3.0(見 package.json)。
下面介紹兩種等價安裝方式,命令來自倉庫 README:
# 從 npm
dsh plugin --profile desktop add dsh-auto-preset-guard
# 從 GitHub
dsh plugin --profile desktop add "github:SternChiri/dsh-auto-preset-guard"
若 desktop profile 的 .npmrc 指向鏡像源(例如 registry.npmmirror.com),剛發佈的版本可能尚未同步,可先把該源的 registry 改回 https://registry.npmjs.org 再安裝。
裝完後重啓 DSH。package.json 聲明瞭 dsh.bundle.patch,reconciliation 會自動在 bundle 中插入 host 行(id: dsh-auto-preset-guard)。
卸載:
dsh plugin --profile desktop remove dsh-auto-preset-guard
關掉或移除本插件後,若當前 DSH 仍帶未修復的裸循環,退出時仍會把 auto 遷到完全權限。是否繼續安裝,取決於你的 DSH 版本是否已含上游修復。
典型用法與驗證¶
日常用法無需額外配置:插件無 UI、無設置項,安裝並重啓後即對 permissionPresets 生效。
手工驗證「重啓後仍保留 auto」:在會話中選自動審批,完全退出 DSH 再打開同一會話,確認預設仍爲 auto 而非完全權限(在仍受 bug 影響的 DSH 版本上,未裝本插件時應能復現相反行爲)。
倉庫 test/ 提供不啓動 DSH 即可跑的腳本,直接驅動安裝目錄內的 cordis 運行時:
node test/verify.mjs
node test/proxy-check.mjs
verify.mjs 覆蓋:運行期卸載集成仍會把 auto 遷到完全權限;root 進入 UNLOADING 後遷移零寫入且身份仍爲 auto;缺集成的會話打開不拋錯;其它發佈錯誤照常拋出。proxy-check.mjs 驗證 auto-review 在 apply 時捕獲的 permissionPresets 引用仍能派發到包裹後的方法。
運行時位於非常規路徑或 asar 內時,可指定:
DSH_CORDIS=/path/to/node_modules/@deepseek-ai/cordis/lib/index.js node test/verify.mjs
調試被攔下的寫入:
DSH_AUTO_PRESET_GUARD_DEBUG=1
(在運行 DSH 或上述測試前於環境中設置。)
適用場景與注意¶
適合誰
- 使用 DSH 0.2.1-rc.* 或尚未包含
4923f3cb修復的版本,且依賴「自動審批」預設的用戶。 - 需要打開歷史會話裏存爲
auto、但當前環境暫時沒有自動審批集成的情況(避免pinInitialPermission直接失敗)。
已知邊界(摘自 README)
- 只攔截
auto → danger-full-access這一種寫入,其它預設變更一律放行。 - 僅在本插件行處於 active 時生效;DSH 仍有裸循環而本插件被禁用時,退出照樣遷移。
- 不修改沙箱值、持久終端或會話數據本體。
- 依賴 cordis 卸載順序,屬於運行時實現細節;上游修復落地後,可原樣卸載本插件,無需額外清理。
安全與信任
DSH 插件以當前 DSH 進程權限運行,安裝前請閱讀 GitHub 倉庫 源碼與 MIT 許可證。社區目錄 SkillHub 插件頁 爲獨立站點,與 DeepSeek / 幻方無官方從屬關係;安裝命令與行爲說明以倉庫 README 爲準。
結尾¶
dsh-auto-preset-guard 在不動上游包的前提下,用運行期包裹保留退出前的「自動審批」選擇,並避免因缺集成而無法打開存爲 auto 的會話。若你已升級到 0.2.2-alpha.2 及以後且行爲正常,可優先考慮依賴上游修復;否則可按上文命令裝入 desktop profile 並重啓驗證。
- 目錄頁:https://www.skillhub.cn/plugins/SternChiri/dsh-auto-preset-guard
- GitHub:https://github.com/SternChiri/dsh-auto-preset-guard