前言¶
DeepSeek Harness(DSH)的模型在 danger-full-access 模式下可以刪掉工作區之外的任何文件。Agent 跑批處理、清理舊版本、刪臨時素材時,一次寫錯的 Remove-Item -Recurse 就可能把整個目錄清掉,而這類操作進入模型上下文時往往沒有明顯的確認環節。
下面是 DreamInsight24 維護的 DSH 插件 敏感數據守衛(Sensitive Data Guard)。它的定位不是事後回收,而是在刪除發生之前攔下來:先備份,再彈窗問你;備份不成功就硬性阻斷,不降級成警告。
這是什麼¶
插件包名 @local/dsh-sensitive-data-guard,版本 0.2.6,適配 DSH 0.2.2-rc.1。它不修改 DSH 代碼,也不依賴 @deepseek-ai/*,而是通過補丁鉤子(cordis.patch.yml)包裝 shell 執行和常見刪除/覆蓋類工具調用,在其中插入判定與備份。
維護者是 DreamInsight24,分類 admin-security。許可證 MIT,見倉庫 LICENSE。
三個區域¶
每個刪除目標先歸入一個區域,區域決定怎麼處理:
| 區域 | 判定 | 處理 |
|---|---|---|
| 工作區 | 當前會話的工作目錄之內 | 完全不干預 |
.dsh |
本機 .dsh 目錄之內 |
靜默備份一次 |
| 敏感區 | 上述兩者之外的任何路徑 | 備份 + 彈窗確認 |
一次操作涉及多個目標時取最嚴格區域。工作區本身優先判定,即如果工作區裝在 .dsh 裏面,按工作區處理。拿不到會話工作目錄時按敏感區處理。
工作區完全不設防是明確的設計決定:插件要防的是模型把工作區之外的目錄一起清掉,不是防你手滑刪自己的項目。
確認流程¶
敏感區刪除命中時,守衛先完成備份,再在界面上彈出確認卡片,工具調用停在那裏等待:
刪除守衛 · 敏感區刪除
允許執行這次刪除嗎?
擬刪除的內容:
• D:\項目\舊版本 1284 個文件,3.7 GB
• D:\素材\臨時 56 個文件,12.4 MB
合計:1340 個文件,3.71 GB
已經提前備份:2026-11-05/<session>/0007
還原命令:node bin/delete-guard.mjs restore 2026-11-05/<session>/0007
[允許執行] [攔截]
點「允許執行」命令立即執行;點「攔截」命令不執行,備份保留;不回答時等 policy.confirmTimeoutMs(默認 5 分鐘),超時按 fail-closed 阻斷,不會自動放行。彈窗發不出去(關了瀏覽器、純 CLI、從子代理發起)同樣阻斷。
答案通過 DSH 的用戶問答通道(ctx.userQuestions,和 ask_user_question 同一套卡片)送回,只回到守衛,模型看不到也拿不到。
需要說明的是,0.2.4 之前的版本用的是 4 位確認碼,碼寫在工具返回值裏,模型自己就能填回去,所以換成了上面的問答通道。確無界面場景下可以切迴文本確認碼:設 policy.confirmVia: 'code',報告裏給 4 位數字,你發給模型、模型帶前綴重發同一條命令即可複用剛纔的備份。這條通道里模型看得見那個碼,因此只應在確實沒有界面時使用。
目標算不出來的時候¶
像 Remove-Item -LiteralPath $env:SOME_VAR -Recurse 這種目標要到運行時才確定的場景,默認(policy.unresolvedAction: 'confirm')仍然彈窗,但正文會明確寫出這次沒有備份,也沒法校驗目標是否落在受保護目錄裏。想改回硬拒就設成 deny。
多數「算不出來」其實能算出來:$x = '字面量' 會進變量表,Get-ChildItem X | Remove-Item 會回溯到 X,[IO.File]::Delete($_.FullName) 會補上上游路徑。
不認識的工具¶
插件自己的工具(比如你自己裝的 config2ds)不在守衛的內置清單裏。默認(policy.unknownTool: 'prompt')守衛彈出一張卡片,把工具名、註冊說明、參數結構、本次調用參數都擺出來,讓你選信任並加入白名單、僅本次允許或攔截。白名單寫入 data/settings.json。彈窗送不到或超時一律按 fail-closed 阻斷。
安裝與啓用¶
在 DSH 的插件管理裏把插件目錄當作本地目錄路徑安裝,或者讓模型調用 plugin_manager 的 install_bundle 傳入絕對路徑。安裝結果應爲 application: applied 且無 warnings。
安裝後做一次自檢:
node bin/delete-guard.mjs status
應看到備份根、健康狀態、批次與佔用、Sysmon 狀態,以及鉤子文件的 ok。自檢的路徑相對插件目錄解析,README 裏後續出現的 backup/、bin/... 這類相對路徑都以 package.json 所在目錄爲基準。
停用在 DSH 裏停用該 bundle 即可,停用立刻失效並還原被包裝的 shell 方法,不會刪除已產生的備份。
設置¶
三個入口改的是同一份狀態,優先級爲 lib/defaults.js 默認值 < cordis.patch.yml 的 config < data/settings.json,改完立即生效,不用重啓:
1、設置 → 敏感數據守衛
2、插件 → 本插件頁面
3、文件:data/settings.json
界面裏能改五項:
| 字段 | 說明 |
|---|---|
triggerLevel |
soft(只備份)/ medium(按閾值)/ hard(一律確認) |
mediumMinFiles |
medium 的文件數閾值(默認 10) |
mediumMinBytes |
medium 的體積閾值(默認 64 MiB) |
protectedPaths |
保護目錄,一行一個,! 開頭表示排除 |
safeTools |
受信任的只讀工具名,一行一個 |
往放寬方向調(hard → medium → soft)不會被攔,但會紅字警告並寫一條審計。完整配置項(備份限額、保留策略、鉤子開關等)在 cordis.patch.yml 裏逐條有中文註釋,是權威來源。config.schema.json 是同一份信息的機器可讀版本,DSH 不會讀它。
保護目錄¶
policy.protectedPaths 是 .gitignore 風格的模式列表,任何級別下都禁止修改,判定發生在「工作區直接放行」之前:
D:\Company\財務
C:\Windows\System32
!D:\Company\財務\公開資料 ← 以 ! 開頭表示放行
規則爲 / 分隔、大小寫不敏感;可帶盤符,不帶則匹配任意盤;* 匹配一段、** 跨段、? 單字符;! 放行;後寫的覆蓋先寫的;不含 / 匹配任意層級,含 / 從盤根錨定。cordis.patch.yml 裏聲明的是部署底線,設置頁只能往上追加,不能刪掉。
插件目錄本身、備份根、審計日誌、profile 配置文件(cordis.patch.yml / cordis.yml / package.json)會自動加入保護,不用手寫。
備份與還原¶
備份目錄結構:
backup\
_store\<aa>\<bb>\<sha256> 內容尋址對象庫(相同內容只存一份)
2026-11-05\<sessionId>\0001\ 批次桶(manifest.jsonl + 硬鏈接鏡像 tree\)
_audit\2026-11-05.jsonl 審計(放行/備份/阻斷/確認/還原/異常)
保留策略:.dsh 最新 10 個批次且不超過 30 天,敏感區 30 天,工作區不產生備份。審計日誌不隨批次刪除。超過總量配額(默認 50 GiB)時新備份直接阻斷,不會把磁盤打滿。
還原會用舊內容覆蓋當前文件,默認逐文件寫回原路徑,目標已存在時拒絕覆蓋,--force 才覆蓋,還原時校驗 SHA-256:
node bin/delete-guard.mjs restore latest --dry-run
node bin/delete-guard.mjs restore 2026-11-05/<session>/0007
node bin/delete-guard.mjs restore latest --to D:\restore-here --force
覆蓋範圍與邊界¶
攔得到的:所有模型工具(write / edit 覆蓋、pwsh / bash 命令、刪除移動類工具、plugin_manager 改動本插件自身);不在內置清單裏的插件工具,默認彈窗問用戶是否信任;所有 shell 命令在 spawn 之前完成判定與備份;命令派生的 Python / Node 子進程通過注入運行時鉤子對 os.remove / shutil.rmtree / fs.rmSync / fs.rename 等做同步校驗;Sysmon 狀態檢測(只讀,只告警,不修改安全配置)。
攔不到的:
- 第三方進程:與 DSH 無關的清理軟件、計劃任務刪文件,插件管不着。
cmd.exe子進程:cmd /c del不經過 Python/Node 鉤子,只有命令文本解析這一層。- 動態或混淆代碼:清空環境、
python -E/-I、native 二進制直接 unlink,鉤子失效。 - 插件自己沒加載或崩了:就沒有門禁,用 status 自檢。
- 工作區不設防。
- 持久 shell 工具:若裝了
tool-pwsh-persistent,它走ctx.terminals而不是ctx.shell,shell 深度層與運行時鉤子都不覆蓋,只剩命令文本解析。本 profile 默認沒裝。
其他情況一律 fail-closed 阻斷:單文件 > 256 MiB、單批 > 10 GiB 或 > 5 萬文件、總量 > 50 GiB、命中保護目錄、目標落在插件自身目錄、插件內部異常。
命令行¶
node bin/delete-guard.mjs status [--root DIR] [--json]
node bin/delete-guard.mjs restore <批次|latest> [--to DIR] [--force] [--dry-run]
node bin/delete-guard.mjs dry-run -- Remove-Item -Recurse -Force D:\tmp\victim
node bin/delete-guard.mjs gc [--root DIR]
dry-run 只報告會備份什麼、多大、是否超限,不刪除也不寫備份,適合部署前先驗證目標路徑是否落在受保護區域。
適用場景與注意¶
適合在跑長時間任務、批量清理或遷移舊目錄的 DSH 會話上啓用,尤其是模型權限爲 danger-full-access、目錄結構裏有明確的舊版本或臨時素材分區時。如果你只想確認某個刪除動作會不會被攔、會不會產生備份,用 dry-run 試一遍最直接。
需要注意幾點。插件以當前 DSH 進程的權限運行,保護的是它能看到與攔到的路徑,上述攔不到的六類邊界不會因爲裝了插件就變成安全邊界。它不修改 DSH 代碼,但攔截的是 DSH 發起的所有破壞性操作,裝到別人的機器上之前先讀倉庫裏的 docs/DEPLOY-CHECKLIST.md。安裝前也應當檢查插件源碼與 MIT 許可證,確認補丁鉤子覆蓋的範圍符合你的使用環境。備份消耗磁盤空間,配額超限後新備份會被阻斷,需要定期用 gc 清理舊批次。
結尾¶
敏感數據守衛的價值在於把「刪之前備份、刪的時候問你、備份不成就不刪」做成默認行爲,區域劃分清晰,失敗方向一致朝阻斷。目錄頁和源碼在:
- https://www.skillhub.cn/plugins/DreamInsight24/dsh-sensitive-data-guard
- https://github.com/DreamInsight24/dsh-sensitive-data-guard