dsh-moongate
suiyideali/dsh-moongate
Learning auto-approval gate for DeepSeek Harness: Flash judging, confirmation-based learning, trust roots and a rule library.
설치
dsh plugin --profile web add github:suiyideali/dsh-moongateREADME
dsh-moongate
一个会从你的审批里学习的 DeepSeek Harness 自动审批门控。
越用越少点:安全操作自动放行,同类操作确认几次后自动沉淀规则,危险操作永远交给你。
致敬原项目:本项目基于 moon09300731/dsh-approval-gate v0.5.0(MIT)扩展而来;
moongate(月门)取意自原作者 IDmoon09300731。详见 原项目。
DeepSeek Harness 默认会在命令和文件修改前询问你。问题是:真实使用中大多数请求都是安全的,人会疲劳、会闭眼点"允许"——审批就变成了走过场。
dsh-moongate 在这个位置做三件事:
- 先判断:越界请求交给 Flash,结合真实 tool call 参数判断是否可回补、是否触碰敏感资源;
- 从你的决定里学:你批准/拒绝过的操作会被记住,本会话直接复用、跨会话晋升、同类操作毕业,全程不需要额外交互;
- 给你透明度和控制权:规则库、命中次数、证据事件、启停/删除/导出,以及审批页的统计、趋势与筛选。
危险类别(删除、凭据、远程/生产、系统、批量)永不自动放行、也永不学习。
目录
为什么是它
审批疲劳是真实问题:用户对权限弹窗的接受率极高,久而久之"允许"变成肌肉记忆。常见的两个极端是:
- 沙箱很安全,但每个新能力都要配置,跨目录/网络很快就会打断工作;
- 跳过权限很省事,但没有任何保护。
dsh-moongate 取中间路线:模型判定 + 人类确认 + 渐进学习。它不会替你决定删除生产库,但会记住"这个测试目录里的写入你已经批准过三次",然后下次不再问。
功能
| 能力 | 说明 |
|---|---|
| Flash 风险判定 | DENY → 信任目录 / 会话记忆 / 白名单 → Flash(SAFE / 硬类别 / 中立)→ 学习 |
| 真实 tool call 判定 | 通过 callId 从 session 事件取实际参数(脱敏、截断 4 KB),不只看模型写的理由 |
| 确认制学习 | 中立操作人工确认到阈值后自动放行;指纹命中 / Flash 语义同类验证 |
| 命令意图学习 | 从真实 bash 参数提炼安全命令意图(git status、npm test、gh pr view 等)并绑定 cwd;npm test 与 npm publish 不再共享同一个学习 key,无法识别的命令不进入学习 |
| 语义近似复用 | 一次人工批准后,同类中立操作由 Flash 做 SAME/DIFFERENT 验证;比较真实参数并要求同一 program(bash)或同一工具;仅放行当前操作,不沉淀规则;默认关 |
| 记住 / 取消记住 | 审批页单行操作;有路径用路径指纹,无路径用整句描述精确匹配;可随时撤销 |
| 信任目录 | 配置一次,目录内操作直接放行(零点击);支持 ~/src 这类前缀 |
| 会话记忆 | 本会话批准过的同指纹操作重复出现时直接放行 |
| 跨会话晋升 | 多会话确认后沉淀全局规则(要求路径指纹、意图信号、无拒绝历史) |
| 签名毕业 | 同类操作累计人工确认后自动毕业为规则(多指纹、2 个会话、无拒绝历史) |
| 自学习(可选) | 从 Flash 连续 SAFE 判定中毕业签名,无需人工确认;默认关,可配阈值/会话/上限 |
| 负反馈 | 拒绝或「撤销改动」会删除对应规则/记忆并升级为永久人工 |
| 规则库 | 白名单/永久人工/信任目录/毕业进度统一管理;搜索、行内编辑、启停、删除、导出 JSON、证据事件 |
| 规则体检 | 泛词 contains、裸 mode、过宽信任目录自动提示,并给出收窄建议 |
| 拒绝计数升级 | 连续 3 次 / 累计 20 次拒绝 → escalate 事件与红色"需人工介入"标记 |
| 两段式判定 | 快筛 ALLOW/REVIEW + 复评;默认关,可指定快筛模型 |
| Shadow 观察 | 先记录“本可自动放行”的候选但仍转人工;候选不写规则/学习/快照,观察稳定后再关闭;重复候选按命令/目录分组并给出一键规则建议 |
| 审批仪表盘 | 统计卡、四段分布、7 天趋势、Top 工具、按项目/目录聚合、筛选搜索、按日期分组时间线 |
| 界面语言 | 跟随浏览器语言自动切换中/英文(记录页、设置页、通知条与主要错误提示) |
安装
当前适配 DeepSeek Harness 0.2.x(实测 0.2.2-rc.1)。安装/更新 host 代码后重载插件(禁用/启用插件行或重启 App);只改 client 时刷新页面即可。
Desktop 用户注意:DSH Desktop 的
desktopprofile 由应用托管,dsh plugin --profile desktop ...会被拒绝(profile "desktop" is managed exclusively by the Electron application)。请在应用的插件管理界面安装/卸载。下面 CLI 示例中的<profile>指你自己用 CLI 管理的 profile(通常是web),不要照抄成desktop。首选安装方式:在 DSH 应用内安装。 不需要命令行;Desktop 用户直接从方式一开始。
方式一:在 DSH 应用内安装(推荐,Desktop 用这个)
不需要命令行,直接在 DSH 侧栏操作:
-
打开侧栏的 插件 页面。
-
点 添加插件 旁的箭头 选择添加插件方式,选 安装第三方插件(直接点 添加插件 也会打开同一个对话框)。
-
在包名输入框填入:
github:suiyideali/dsh-moongate -
点 安装;看到安装结果后点 立即启用,再按提示重载/刷新。
对话框也接受 npm 包名、压缩包和本地绝对路径;这里用 Git 地址,所以不需要先发布 npm。Desktop 的
desktopprofile 由应用托管,插件管理界面就是 Desktop 的正确安装入口。
方式二:用 CLI 安装(仅 CLI 管理的 profile)
dsh plugin --profile <profile> add github:suiyideali/dsh-moongate
发布到 npm 后也可以:
dsh plugin --profile <profile> add dsh-moongate
从上游迁移(Desktop 版)
- 备份
~/.dsh/auto-approve/、profile 的cordis.patch.yml和pnpm-workspace.yaml。 - 在插件管理里禁用/移除
dsh-approval-gate;并从pnpm-workspace.yaml删除'dsh-approval-gate@0.5.0': ...这一行patchedDependencies。 - 安装
dsh-moongate,重启/重载后确认 profile 里只有这一条审批插件。 - 数据目录仍为
~/.dsh/auto-approve/,已有规则/学习记录直接沿用;auto-approve权限预设保留。
不要同时启用
dsh-approval-gate和dsh-moongate,否则两个插件会同时抢approval/request。
方式三:给上游包打补丁
如果你在用 CLI 管理的 profile,并且已经安装了上游 dsh-approval-gate@0.5.0,可以只应用完整 diff(patches/):
# 1) 安装上游包(若尚未安装)
dsh plugin --profile <profile> add dsh-approval-gate@0.5.0
# 2) 复制补丁
cp patches/dsh-approval-gate@0.5.0.patch ~/.dsh/profiles/<profile>/patches/
# 3) 在 ~/.dsh/profiles/<profile>/pnpm-workspace.yaml 增加
# patchedDependencies:
# 'dsh-approval-gate@0.5.0': patches/dsh-approval-gate@0.5.0.patch
# 4) 重装应用补丁(pnpm 版本需匹配 profile 的 store)
cd ~/.dsh/profiles/<profile>
pnpm install
补丁方式保留上游包名与内部 id(
dsh-approval-gate),适合已经安装上游的人;不要和 fork 包dsh-moongate同时安装。数据目录同为~/.dsh/auto-approve。
配置权限预设(所有安装方式都需要)
权限预设表在组合时冻结,必须手动加一条到 profile 的 cordis.patch.yml:
- id: permission
name: '@deepseek-ai/dsh-permission-presets'
config:
presets:
read-only:
sandbox: read-only
approval: ask
workspace-write:
sandbox: workspace-write
approval: ask
danger-full-access:
sandbox: danger-full-access
approval: never
auto-approve:
sandbox: workspace-write
approval: ask
name: 自动审批(Flash)
description: 学习式自动审批:写工作区自动放行,同类操作确认后自动同意,危险操作转人工。
重启或重载后,会话权限下拉会出现「自动审批(Flash)」。
快速开始
- 在会话权限下拉选择 「自动审批(Flash)」——只对该会话生效,其他会话不受影响。
- 第一次打开设置 → 自动审批 → ⑥ 自动学习 时,会看到一次性引导:
- 保持推荐(保守):会话记忆/跨会话晋升/签名毕业已开启,自学习关闭;
- 开启自学习(激进):从 Flash 的
SAFE判定直接学习,无需人工确认。
- 正常干活:安全操作自动放行;不确定的操作弹窗给你;你批准的同类操作会逐渐沉淀。
- 需要更可控时:
- 审批页每行 「记住这次操作」:立刻写入白名单;已记住可 「取消记住」;
- 设置 → ⑦ 规则库:搜索、行内编辑、启停、删除、导出、复制证据事件;
- 设置 → ⑥ 自动学习:调阈值、会话数、自学习参数。
界面
审批页(轨迹右侧「审批」标签)是一个仪表盘,而不是简单列表;它把「看见异常、理解放行、控制学习」放在同一个视图里。
记录 tab
| 区块 | 展示什么 | 回答的问题 |
|---|---|---|
| 需关注 | 拒绝 + 升级的汇总(仅在存在这类记录时出现),附「只看这些」按钮 | 有没有需要我处理的事? |
| 概览(默认展开,可收起) | 五张统计卡:自动放行 / Shadow 候选 / 人工通过 / 已拒绝 / 需人工介入,带百分比 | 这个会话的审批结构如何? |
| 四段分布条 + 规则概览:规则总数 / 自学习 / 毕业 / 信任目录 | 自动化和学习各占多少? | |
| 最近 7 天审批趋势 + Top 工具 | 什么时候、哪些工具最常触发审批? | |
| 按项目/目录聚合(全部会话):项目名、路径、自动率条、总数/自动/拒绝/Shadow | 哪些项目最常触发审批、自动放行率如何? | |
| 筛选 | 全部 / 自动 / 人工 / 拒绝 / 升级 / 需关注 chips + 工具、理由、参数搜索 | 快速定位一类记录 |
| 时间线 | 按日期分组;每行工具、判定标签、时间、理由、真实参数、记住/取消记住、文件与 diff 快照 | 这一次到底发生了什么、为什么放行、能不能撤销? |
概览默认展开,进入审批页先看到统计全貌;可点「收起」回到时间线优先。带快照的行会提示「已保留改动快照 · 可在下方 diff 中撤销」,把撤销路径放在决策现场。
示意图用于展示信息结构;实际样式以插件渲染为准。
设置 tab
审批页内直接嵌入完整的「自动审批」设置,和设置页是同一套配置:
- 顶部粘性子导航:初始化 / 判定管道 / ① DENY / ② 白名单 / ③ 永久人工 / ④ Flash / Shadow / ⑤ 学习 / ⑥ 自动学习 / ⑦ 规则库;
- 点击平滑滚动到对应卡片,修改热生效,不必来回切换页面;
- 设置页(设置 → 自动审批)仍保留同一入口。
八张配置卡片:
| 卡片 | 内容 |
|---|---|
| ① DENY 层 | 不可逆危险词黑名单 |
| ② 白名单 | 自动放行的规则(来源/命中次数) |
| ③ 永久人工 | 拒绝升级的规则 |
| ④ Flash 判定 | riskyThreshold、judgeTimeoutMs |
| Shadow | 观察模式开关;候选只记录不自动放行 |
| ⑤ 学习沉淀 | 正在学习的 key、确认进度,可终止 |
| ⑥ 自动学习 | 会话记忆、晋升、毕业、自学习、两段式、语义复用开关与参数 |
| ⑦ 规则库 | 四类规则统一管理 + 行内编辑 + 规则体检 + 导出 |
Shadow 的边界:观察期内,候选操作即使被你拒绝,也不会写入
denyRules(观察模式不产生任何学习副作用)。关闭 Shadow 后,如果希望某类操作继续走人工,请先在规则库里添加“永久人工”规则,或保留会命中该操作的拒绝规则。
工作原理
flowchart TD
A[沙箱越界 approval/request] --> B{会话预设 = auto-approve?}
B -- 否 --> H[交给人工 / 其他应答者]
B -- 是 --> C{DENY 危险词}
C -- 命中 --> H
C -- 未命中 --> D{信任目录 / 会话记忆 / 白名单}
D -- 命中 --> E[自动放行]
D -- 未命中 --> F[Flash 判定<br/>工具 + 真实参数]
F -- SAFE --> E
F -- 硬风险类别 --> H
F -- 中立 --> G[确认制学习 n/N]
G -- 批准 --> I[计数 / 样本 / 晋升 / 毕业]
G -- 拒绝 --> J[denyRule 永久人工]
- 只拦截沙箱越界请求:普通工作区内读写不会经过它。
- 按会话门控:没有选择「自动审批(Flash)」的会话完全不受影响。
- fail-safe:Flash 超时/异常/输出无法解析 → 一律转人工,绝不自动放行。
- 真实参数优先:判定输入来自
tool/call事件(按callId关联),并对api_key/token/password/authorization/cookie等做脱敏;缓存上限 8 KB。
学习模型
| 层 | 信号来源 | 生效范围 | 默认 |
|---|---|---|---|
| 记住(手动) | 你点「记住这次操作」 | 全局规则 | 可用 |
| 信任目录 | 你的显式配置 | 目录前缀 | 空 |
| 命令意图 | 真实 bash 参数中的安全命令 + cwd | 同命令、同目录 | 开(保守识别) |
| 会话记忆 | 本会话中的人工批准 | 当前会话 | 开 |
| 跨会话晋升 | 多个会话的人工批准 | 全局规则 | 开(2 会话) |
| 签名毕业 | 同类操作多次人工批准 | 全局规则 | 开(3 次 / 2 会话) |
| 自学习 | Flash 连续 SAFE 判定 | 全局规则 | 关(可开) |
自学习默认关闭是有意的:它是唯一没有任何人工标签的层,默认打开会把模型误判固化成规则。开启后仍有护栏:路径签名、无拒绝历史、会话数/次数阈值、规则数量上限(50),拒绝/撤销会删除对应规则与进度。
配置
数据统一在 ~/.dsh/auto-approve/,修改 allowlist.json 即时生效(热更新):
| 字段 | 默认 | 说明 |
|---|---|---|
denyKeywords | 内置 | 命中即转人工的不可逆危险词 |
allowRules | 工作区写入 | 白名单规则:tool/mode/category/contains/signature/disabled |
denyRules | [] | 永久人工规则 |
hardCategories | deletion/credential/remote/system/bulk | 硬风险类别,永不学习 |
riskyThreshold | 3 | neutral 操作确认阈值 |
judgeTimeoutMs | 20000 | Flash 判定超时(重试 1 次) |
trustRoots | [] | 信任目录,范围内直接放行 |
sessionMemory | true | 会话内批准记忆 |
promotionSessions | 2 | 跨会话晋升所需会话数(无意图信号时 3) |
graduationThreshold | 3 | 签名毕业所需人工确认次数(无意图信号时 4) |
graduationSessions | 2 | 毕业所需会话数 |
selfLearn | false | 自学习开关 |
selfLearnThreshold | 5 | 自学习所需连续 SAFE 次数 |
selfLearnSessions | 2 | 自学习所需会话数 |
selfLearnMaxRules | 50 | 自学习规则上限 |
twoStage | false | 两段式判定开关 |
shadow | false | Shadow 观察模式;候选只记录不自动放行 |
semanticReuse | false | 一次人工批准后,用 Flash 语义验证同类中立操作;不沉淀规则 |
stage1Provider / stage1Model | 空 | 快筛模型(留空用默认) |
denyEscalateConsecutive | 3 | 连续拒绝升级阈值 |
denyEscalateTotal | 20 | 累计拒绝升级阈值 |
文件:
| 文件 | 用途 |
|---|---|
allowlist.json | 规则与配置 |
learning.json | 确认制学习计数与样本 |
memory.json | 跨会话记忆与毕业/自学习进度 |
audit.log | 判定审计(ALLOW / TRUST / SESSIONMEM / LEARN / GRADUATE / PROMOTE / NEGATIVE / ESCALATE / …) |
events.jsonl | 审批事件(供审批页,含 remembered、args 等字段) |
snapshots/ | 自动放行前文件快照(供 diff / 撤销) |
安全模型
- 硬风险永不自动:删除/覆盖不可再生数据、凭据、远程/生产、系统路径、批量不可回补,命中即人工,不计数、不学习。
- 拒绝优先:被拒绝过的指纹/签名升级为永久人工,且会删除对应学习规则与记忆。
- 撤销降级:在审批页撤销一次自动放行的改动,会触发负反馈,删除对应规则。
- 输入脱敏:真实参数在进入模型前做密钥脱敏并截断。
- 规则可审计:每条规则带来源、创建时间、命中次数、最近命中;记住/自学习规则带证据事件。
- 规则体检:泛词
contains、无tool/contains的裸规则、danger-full-access裸规则、~//级信任目录会被标红并可一键停用。
⚠️ 自动审批会显著降低人工介入。请在可信环境使用;生产数据、支付、远程系统等场景请保持人工审批或
ask预设。
兼容性
- 面向 DeepSeek Harness 0.2.x,已在 0.2.2-rc.1 验证;
- 修复了上游在 0.2.x 上的
permissionPresets.current(session)API 适配与 FlashreasoningEffort: off兼容问题; - DSH 升级后如 API 变化,需要重新适配;欢迎提 Issue/PR。
开发与测试
npm test # node --check + smoke tests
CI(.github/workflows/ci.yml)会执行:
node --check src/index.mjs与node --check client.js;scripts/smoke.mjs(插件导出、client 关键标记、补丁存在性);- 下载上游
dsh-approval-gate@0.5.0并验证补丁可干净应用; - LICENSE 检查。
本地修改流程:
- host 改动:改
src/index.mjs→ 重新应用 pnpm patch(或直接替换 profile 内包)→ 重载插件; - client 改动:改
client.js→ 刷新页面; - 提交前跑
npm test。
路线图
- 规则库行内编辑(tool/mode/category/contains/描述);
- 语义近似复用(一次批准后用真实参数、同一 program/工具做 Flash 同类验证,仅放行当前操作);
- Shadow 模式:先记录"本可自动放行"的候选,观察期后启用;
- 按项目/目录统计(全部会话 + 未知目录兜底,趋势后续增强);
- i18n(跟随浏览器语言,主要界面中英切换);
- 命令意图学习(安全 bash 命令 + cwd 独立计数与规则,无法识别的命令不学习);
- Shadow 候选分组与规则建议(同命令/目录重复候选聚合,手动创建规则)。
FAQ
Q:为什么自学习默认关闭? A:它是唯一不从人工批准中学习的层。默认开启等于替用户做激进决定;需要时在⑥一键开启。
Q:和上游 dsh-approval-gate 能同时装吗?
A:不建议。两者会争夺同一个 auto-approve 预设与 approval/request 事件;请二选一。
Q:学习数据存在哪?升级会丢吗?
A:~/.dsh/auto-approve/。卸载/重装插件不会删除;DSH 升级后请先备份该目录。
Q:只信任某个目录怎么写?
A:⑥ 或 ⑦ → 信任目录,填 ~/src(支持 ~ 前缀),范围直接放行,仍受 DENY 与硬风险规则约束。
Q:为什么审批页看不到记录? A:当前会话还没有越界请求,或没有选中「自动审批(Flash)」预设。
参与贡献
- 先开 Issue 描述场景/复现,再提 PR;
- 每个 PR 会自动请求
@mochazZZ(superagent)review,合并前请等它给出结论; - 保持
npm test通过,新增行为尽量补 smoke 断言; - 不要提交本地路径、凭据或测试残留;
- 涉及安全语义的改动请在 PR 里写清威胁模型与回退方式。
原项目 / Credits
本项目基于 moon09300731/dsh-approval-gate v0.5.0(MIT):
- 原项目:https://github.com/moon09300731/dsh-approval-gate
- 作者:moon09300731
- 继承:Flash 判定管道、确认制学习、设置页规则卡片、审批视图、diff 撤销与快照
- 本 fork 新增:真实参数判定、记住/取消、信任目录、会话记忆/跨会话晋升、签名毕业、自学习、规则库、审批仪表盘等(详见 FORK-CHANGES.md)
moongate(月门)取意自原作者 ID moon09300731,作为致敬。感谢原作者的设计与实现;如果你喜欢这套思路,也请给原项目点一个 Star。
原版权归原作者所有,修改部分同样以 MIT 发布,见 LICENSE。
License
MIT © 2026 moon09300731(原项目)及 dsh-moongate 贡献者。修改部分不提供担保。