dsh-permission-rules
把工具调用的裁决权拿回自己手里——每一条 allow / deny / ask 都写在 YAML 里,确定、即时、可审计。
面向 DeepSeek Harness 的 Claude Code 风格声明式权限中间件:规则裁决已知的,评审模型裁决未知的;另带一套 Codex 风格的进程级网络策略与本地代理,管住 shell 子进程的出站流量。
安装 · 配置 · FAQ · 简体中文 · English · Español · Português · हिन्दी
dsh plugin --profile <name> add dsh-permission-rules
社区插件,与 DeepSeek 官方无关。唯一仓库:
它是什么
dsh-permission-rules 在 tools/pre-execute waterfall 上为每次工具调用前置一份有序的 allow / deny / ask 规则列表——确定、即时、可审计,由你用纯 YAML 编写。规则裁决已知的调用;没把握的交给官方审批接缝,由评审模型或人裁决。它另外带一层 Codex 风格的进程级网络策略:shell 子进程的出站流量经内置本地 HTTP/CONNECT 代理,由网络规则或映射到官方沙箱预设的三档模式裁决。
结构:两条通道(工具调用 / shell 出站)汇入同一条有序规则链,首个匹配胜出;随后分流为工具调用与网络出口两组裁决,收束于两个仅日志审计事件。
三步上手
- 安装(三选一):
# git 通道(最新 main;prepare 脚本只用生产依赖构建)
dsh plugin --profile web add github:PerryLink/dsh-permission-rules
# npm 通道(已发布版本)
dsh plugin --profile web add dsh-permission-rules
# tarball 通道:本仓库 pnpm pack 后
dsh plugin --profile web add ./dsh-permission-rules-<version>.tgz
- 写第一条规则(项目根的
.dsh/rules.yaml;不写也能用,内置高危基线默认开启):
# <project>/.dsh/rules.yaml
rules:
- match: { tools: [bash, pwsh], params: { command: "git push*" }, paths: ["/secrets/"] }
action: deny
reason: "No pushes from protected paths"
- match: { tools: [edit, write] }
action: ask
reason: "File writes need confirmation"
- 验证已生效:
# 重启 profile 后确认插件行已挂载
dsh --profile web --dump-config | grep -A4 'id: permission-rules'
# 用真实命令面试跑一条假设调用,不执行任何工具
/rules test bash {"command":"git push origin main","cwd":"src/secrets/app"}
"bash" matches rule 1 (deny): 禁止 push 到受保护路径
卸载:dsh plugin --profile web remove dsh-permission-rules(或从 profile patch 删掉该行)。
从 DSH Desktop 市场安装
所有 PerryLink 插件均可在 DSH Desktop 内置市场中浏览:市场 → 来源 → 添加来源 → 粘贴 https://perrylink-dsh-catalog.perrylink.workers.dev/catalog-source.json → 选中。安装仍需通过市场的 npm 身份校验与你的确认。
核心能力
dsh-permission-rules 在 tools/pre-execute 上为每次工具调用前置有序规则——确定、即时、可审计:
deny阻断调用;规则的reason成为模型可见的错误。ask走官方审批接缝(挂载dsh-auto-review用第二模型作答,或由人作答;两者皆无时 harness 失败关闭)。allow(及未命中)严格经next()委托——下游监听器绝不会被短路。
permissionRules/decision 会话事件审计落盘(仅日志——不会向模型上下文额外注入任何内容)。
- 丰富匹配 —— 工具名 glob(含
mcp__)、agent 身份选择器(main/subagent/preset:)、参数键/值 glob 或 正则(含!pattern取反与absent键维度)、任意嵌套深度的工作区相对路径 glob、when宿主条件(环境变量、平台),以及 shell 命令分解(argv:命令词、参数 token、管道签名)用于 token 级精确命令匹配。 - 内置高危基线 —— 随附的 deny/ask 规则集(破坏性命令、权限提升、下载即执行、敏感路径),默认开启并追加在用户规则之后(更近的用户规则可覆盖);用
builtin.enabled开关。 - 分层规则文件 —— 可选
searchUp从会话 cwd 到文件系统根合并每个.dsh/rules.yaml,就近优先。 - 试运行上线 ——
enforce: false审计策略会做什么,同时放行每个调用。 - 热重载 —— Chokidar 监听带去抖;损坏的编辑保留旧规则、绝不崩溃。在 WSL 主机上(或规则文件位于
/mnt/<盘符>下时)监听切换为轮询,因为该处的原生变更事件不可靠。 - 失败大声 —— 非法 YAML、未知 action/字段、坏 glob/正则、易回溯模式或超过
maxRules的规则在加载期失败。
命令与工具面
| 表面 | 类型 | 说明 |
|---|---|---|
| tools/pre-execute | listener | 首个匹配的 allow/deny/ask 规则 + 网络 URL 候选抽取 |
| /rules | command | list · reload · decisions [n] · test |
| permissionRules/decision | event | 每次命中与透传的仅日志审计 |
| permissionRules/network | event | 被拒连接的代理层审计 |
| HTTP/CONNECT proxy | service | 治理 shell 子进程流量的内置本地代理 |
| settings page | client | 网络模式编辑器、规则编辑器、块计数器、近期拦截(每条可一键放行) |
/rules list the active rules, their source files, and any last-reload error
/rules list explicit alias for the bare listing
/rules reload re-read the rule-file chain for this workspace
/rules decisions [n] show the last n permission decisions of this session (default 10)
/rules test <tool> <json> dry-evaluate the rules against a hypothetical call
/rules test 也接受前置标志:--cwd 、--env KEY=VALUE(可重复)、--agent (可重复)与 --platform 。在多文件链(如 searchUp)中,每条列出的规则行都归属到其自身源文件。
示例
以下为插件真实入口;安装后调用一个即可。
详细示例 — 命令 /rules test bash {"command":"git push origin main","cwd":"src/secrets/app"},输出:
"bash" matches rule 1 (deny): 禁止 push 到受保护路径
Observed from test/command.spec.ts:204-219 (assertions at :209-213); src/prose.ts:121
失败分支 — 输入 /rules test bash {not json,输出:
Invalid JSON arguments "{not json": the arguments must parse as JSON.
Observed from plugins/dsh-permission-rules/src/prose.ts:123; plugins/dsh-permission-rules/src/runtime.ts:1266-1272; plugins/dsh-permission-rules/test/command.spec.ts:221-228
简短示例:tools/pre-execute · /rules test
规则语法
# <project>/.dsh/rules.yaml
rules:
- match: { tools: [bash, pwsh], params: { command: "git push*" }, paths: ["/secrets/"] }
action: deny
reason: "No pushes from protected paths"
- match: { tools: [edit, write] }
action: ask
reason: "File writes need confirmation"
- 匹配维度 ——
tools(glob,含mcp__*)、agents(main/subagent/preset:;未知身份永不匹配——失败关闭)、params(键/值 glob 或正则,!pattern取反,absent键维度)、paths(任意嵌套深度抽取的工作区相对 glob)、when(env变量 glob/正则 + 封闭platform列表),以及network(domains/ips/ports/schemes——glob、通配符、CIDR、端口范围)。 - 动作 ——
allow/deny/ask,按文件顺序求值,首个命中胜出。 - 规则元数据 ——
enabled: false(可见但失效)、description、tags;未知字段加载失败。 - Schema —— JSON Schema 见 docs/rules-format.schema.json(编辑器补全
# yaml-language-server: $schema=...);完整词汇表与 5 条安全基线见 docs/rules-format.md。
网络策略
Codex 风格的进程级网络策略:shell 子进程流量经内置本地 HTTP/CONNECT 代理,每个连接由有序网络规则或映射到官方沙箱预设的三档模式裁决:
deny-all—— 只读沙箱预设:阻断所有出站。whitelist—— workspace-write 预设:放行列表目标,其余按unlisted: ask(或deny)。allow-all—— danger-full-access 预设:放行一切。auto(默认)—— 跟随沙箱预设;无沙箱策略服务的宿主上解析为autoFallback(allow-all)。
- 匹配 ——
match.network用domains/ips/ports/schemes(glob、通配符、CIDR、端口范围;数值型 YAML 端口可接受)。tools/pre-execute热路径上的 URL 候选抽取作用于 web 工具参数与嵌入 bash/pwsh 命令文本的 URL;回环目标可按loopback策略短路规则。IPv4 映射的 IPv6 字面量在匹配前归一化为 IPv4 形式;代理按裁决到的地址建连,不做二次 DNS 解析——裁决未解析出任何地址的连接以 502 关闭失败,绝不按名字拨号。 - 上游链式 ——
network.upstreamProxy(默认off)把本代理放行的连接送上上游代理:CONNECT 向上游要一条隧道(CONNECT host:port),纯 HTTP 请求以绝对形式转发给它。被拦截的目标永远到不了上游——它照旧收到本插件的结构化 403。即使配置了上游,两类情况也绝不链式:回环目标(本机之外的代理无法路由它的回环),以及由ips作用域规则产生的任何裁决(链式会把主机名交给上游,"连接落在规则看过的地址上"(issue #21)恰恰会在规则真正在意地址的地方不再成立;这些裁决仍按裁决到的地址直连),再加上目标 scheme 没有可用上游的情况。上游自身的主机名是运维配置而非 agent 输入,不参与这些规则的裁决。带凭据的 URL 绝不原样输出:警告、/rules network与设置页快照都会把口令打码(http://user:@host:port)。上游不可达、超时(10 秒)或返回非 2xx 一律 502*——刻意没有静默回退直连,配置错误因此始终可见。 - 审计 —— 被拒连接向所属会话追加
permissionRules/network(同样的自适应ignorable门),块计数器与近期拦截在/rules network与设置页展示。 - 诊断 —— 被拦截的连接带
[network: …]消息,点名被拦目标、做出裁决的模式或规则,以及处置办法。 - 设置页放行 —— 每条近期拦截都提供放行动作:它在真正裁决该连接的最近一个规则文件的最前面(索引 0)写入一条最小的
match: { network: { domains: [<主机>] } }/action: allow规则——被拦截连接所归属工作区的项目文件(配置了绝对rulesFile时即该文件);对无会话归属的宿主级拦截,则写宿主链解析出的文件(绝对rulesFile→ 已存在的→ 配置的/ fallbackPath→,不存在则创建)。加载了多个工作区时,页面先提供工作区选择器——任何已加载的工作区链都优先于宿主链。之所以放在索引 0:规则首个匹配生效,追加在既有/ deny之后只会成为死文本。只写domains:该维度包含子域且与端口/scheme 无关,因此同一主机在下一个端口上不会被重新拦截;既有注释与未改动规则原样保留,文本与手工编辑走同一道校验门。写入即刻生效——缓存的工作区链与无会话宿主链都会重读,无需重启、无需/rules reload——随后重新计算裁决,因此提示报告的是真实结果,绝不在连接仍被拦截时声称成功。以下情况一律拒绝且磁盘文件分毫不动:未知工作区、不在已知规则源内的目标、只读的内置基线、无法读取或解析的文件;连接已被放行时不写入任何内容。network.allowHostAction: false隐藏按钮并让 RPC 拒绝。
配置
所有可调项均为 Schemastery Config 字段(可在 cordis.yml 中修改)。按 id 覆盖会整行替换——重述你需要的每个键。在 0.1.7-alpha 宿主上每个字段都以 .volatile() 声明,因此还可在 Plugins 设置页就地编辑:编辑直接写入运行中的引用、不重挂插件,运行期在下次读取时取到新值,且改动 network.proxyPort、proxyBind、injectEnv 或 noProxy 会立即重绑本地代理。数值边界声明在 schema 上,配置编辑器在持久化前用该 schema 解析合并后的配置,故越界值在写入时即被拒绝。Schemastery 早于 volatile() 的宿主上,这些字段只能通过 cordis.yml 修改。
最常用键:
| 键 | 默认值 | 含义 |
|---|---|---|
| rulesFile | .dsh/rules.yaml | 规则文件位置;相对 = 相对调用会话 cwd 解析,绝对 = 全局并在挂载时校验 |
| fallbackPath | (none) | 按 cwd 发现无果时使用的规则文件;挂载时校验 |
| badFilePolicy | fail | 坏规则文件:fail 响亮地令待处理工具调用出错;ignore-with-warning 警告并空继续 |
| maxRules | 256 | 生效源链上规则总数的硬上限 |
| patternMode | glob | params/paths/when.env 模式风格:glob 或 regex(工具名始终为 glob) |
| watch | true | Chokidar 监听 + 变更重载 |
| enforce | true | false = 试运行:deny/ask 命中带 dryRun 标记审计,每个调用都透传 |
| language | en | /rules 输出语言:en、zh、es、pt、hi |
完整配置表(29 个键)
| 键 | 默认值 | 含义 |
|---|---|---|
| rulesFile | .dsh/rules.yaml | 规则文件位置;相对 = 相对调用会话 cwd 解析,绝对 = 全局并在挂载时校验 |
| fallbackPath | (none) | 按 cwd 发现无果时使用的规则文件;挂载时校验 |
| badFilePolicy | fail | 坏规则文件:fail 响亮地令待处理工具调用出错;ignore-with-warning 警告并空继续 |
| maxRules | 256 | 生效源链上规则总数的硬上限 |
| maxCachedWorkspaces | 512 | 缓存的工作区规则加载硬上限(LRU 逐出) |
| patternMode | glob | params/paths/when.env 模式风格:glob 或 regex(工具名始终为 glob) |
| watch | true | Chokidar 监听 + 变更重载 |
| watchStabilityThresholdMs | 200 | 重载去抖窗口(毫秒) |
| language | en | /rules 输出语言:en、zh、es、pt、hi |
| caseInsensitivePaths | (win32) | paths 模式与工作区根比较忽略 ASCII 大小写;Windows 上为 true |
| audit | all | 审计粒度:all 记录每次命中与透传;hits 跳过透传事件 |
| searchUp | false | 从会话 cwd 向上遍历父目录并合并每个找到的规则文件,就近优先 |
| maxGlobStars | 2 | 每个 glob 模式无界 /* 量词的硬上限 |
| enforce | true | false = 试运行:deny/ask 命中带 dryRun 标记审计,每个调用都透传 |
| allowUnmarkedAudit | false | 前标记宿主丢弃 ignorable 标记;插件以一次性警告禁用会话日志审计。设 true 重新启用 |
| network.enabled | true | 代理、环境注入与 web 工具模式默认的总开关 |
| network.mode | auto | 策略模式:auto 跟随沙箱预设,或 deny-all / whitelist / allow-all |
| network.autoFallback | allow-all | auto 无沙箱策略服务时使用的模式 |
| network.unlisted | ask | 白名单模式下未命中规则目标:ask 或 deny |
| network.proxyBind | 127.0.0.1 | 本地代理绑定地址(仅回环) |
| network.proxyPort | 0 | 本地代理端口;0 选空闲临时端口 |
| network.proxyMaxRecent | 100 | 设置页保留的近期拦截记录上限 |
| network.loopback | allow | 回环目标:allow(Codex 对齐)或 policy |
| network.injectEnv | true | 是否为子进程注入代理环境变量 |
| network.noProxy | clear | 子进程 NO_PROXY 处理:clear 强制策略或 preserve |
| network.upstreamProxy | off | 本插件放行连接的上游代理:off 直连、inherit 沿用启动环境的代理名,或显式 http(s):// 代理 URL |
| network.allowHostAction | true | 设置页逐条「放行」动作:false 隐藏「放行」按钮并让 permissionRules/allowHost RPC 拒绝(规则编辑器不受影响) |
| builtin.enabled | true | 内置高危基线:false 完全禁用随附的 deny/ask 规则集 |
| builtin.path | (随附) | 替换基线文件(绝对路径,或相对 process.cwd());挂载时校验 |
FAQ
规则文件存在哪?插件会不会乱写我的文件?
规则从磁盘读取:项目根的 .dsh/rules.yaml,或配置的 rulesFile / fallbackPath,searchUp 时逐级向上合并。常规裁决路径不写任何规则数据。唯一的写面是设置页的规则编辑器,以及「放行」动作——后者只向已知规则源的最前面写一条最小 allow 规则,写前重新走一遍与手工编辑相同的解析/编译校验(详见「网络策略」)。
没有挂载 dsh-auto-review 时,ask 会怎样?
ask 走官方审批接缝:挂了 dsh-auto-review 就由只读的第二模型裁决,否则由人作答;两者都不存在时 harness 失败关闭,调用不会静默放行。本插件自己绝不生成子代理、不调用模型——产出 ask 就是它工作的终点。
宿主自身的出站请求会被这个代理拦住吗?
不会。注入的代理环境覆盖派生的 shell 子进程,以及在请求时读取代理变量名的消费者;不覆盖宿主进程自身基于 fetch 的流量——launcher 在第一个插件挂载前就用启动环境装好了 undici 的全局 dispatcher,该 dispatcher 按策略而非按环境路由。因此供应商端点不需要允许规则,network.injectEnv: false 也不会把宿主进程移出任何东西。2026-09-10 实测于 Node 22,可用 scripts/host-egress-probe.mjs 复现。
热路径上的性能开销多大?
规则求值是纯内存的首个匹配遍历,不调模型、不发网络请求;命中的裁决与透传只追加会话审计。监听失败只告警并保留旧规则;规则文件多时可把 audit 设为 hits 跳过透传事件,或用 maxRules / maxCachedWorkspaces 设定上限。
会和其他插件抢事件、命令名或 slot 吗?
不会。工具名带命名空间、不占裸名,服务键 permissionRules / permissionRulesRuntime 不是内置 seam,也不注册客户端 slot 与 webServer 前缀,patch 只 insert 自己那一行;共享事件一律经 next() 委托。逐条论证见「与其他 DSH 插件的互操作性」。
安全边界
- 是策略,不是内核。
paths候选只来自一组文档化的参数键(任意嵌套深度、有深度上限),且仅工作区相对路径匹配。 - 这里没有评审者。 插件绝不生成子代理或调用模型——产出
ask决策就是其工作的终点。 - 不改沙箱。 OS 级沙箱策略属于沙箱接缝,与本插件无关。
- 响亮地拒绝错误配置。 未知 YAML 字段、未知 action 与坏模式在加载期被拒绝。
- 回溯界限。 glob 模式以
maxGlobStars限制无界星号展开;正则模式拒绝嵌套无界量词与量化重叠字面交替。 - 关闭失败的拨号。 明文 HTTP 转发与 CONNECT 隧道只连接裁决到的地址;裁决未解析出任何地址的 allow 以 502 关闭失败,而不是按名字拨号(issue #23)。
权限与数据
- 权限:workshop 清单声明
files:read、files:watch、files:write、session:append与network:outbound。ask决策走官方审批接缝——不重实现、不绕过。 - 数据:规则文件从磁盘读取;常规裁决不写任何规则数据,唯一的写面是设置页的规则编辑器与「放行」动作。无模型调用、无评审子代理。
- 会话日志:
permissionRules/decision绝不注入模型上下文,并以信封的ignorable: true标记追加,任何 harness 构建都能加载日志。
已知限制
- 前标记宿主与拒绝型宿主上的审计标记。
permissionRules/decision以ignorable: true追加;Session.append早于该标记的宿主(0.1.0-rc.1–rc.7与0.1.1-rc.1–rc.7线)静默丢弃它,0.1.2-rc线沿用 alpha.5 表面(append 无任何选项能写该标记),0.1.2-alpha线在读取时连已标记的插件事件也拒绝,0.1.3-alpha与0.1.5-alpha线同样沿用 surface-only 追加签名(已在已发布的0.1.3-alpha.1/0.1.5-alpha.1包上核验)——运行时在首次追加前即预检这些线并以一次性警告禁用会话日志审计。跨代迁移同样拒绝已标记的审计行:0.1.3-alpha的 v1→v2 门拒绝未知 v1 事件,0.1.5-alpha的 v2→v3 门拒绝一切未分类事件(其清单冻结为已发布 v2 词汇),故在 0.1.3 宿主打开日志前stripv1 行、在升级到 0.1.5 宿主前stripv2 行。v3 原生日志接受已标记的插件行,只需repair。设allowUnmarkedAudit: true重新启用;用scripts/repair-session-logs.mjs修复已写日志(标记无济于事的宿主用其strip模式移除审计行)。 - 路径候选是启发式的。 只有文档化的参数键参与路径匹配,且工作区相对匹配仅在
caseInsensitivePaths开启时忽略 ASCII 大小写。 - glob 是保守子集。 无花括号展开——写两个模式,或用正则模式。
- 正则回溯守卫是结构性的、非穷尽的。 对不可信文件优先用 glob 模式。
- 宿主自身的出站请求不经过本代理。 注入的代理环境覆盖派生的 shell 子进程(这正是注入的用途),以及在请求时读取代理变量名的消费者;它不覆盖宿主进程自身基于
fetch的流量——launcher 在第一个插件挂载之前就用启动环境装好了 undici 的全局 dispatcher,该 dispatcher 按策略而非按环境路由,且 Node 在启动时采样代理环境,因此后挂载的插件无法改变它。结论:供应商端点不需要允许规则,network.injectEnv: false也不会把宿主进程移出任何东西。2026-09-10 实测于 Node 22;用scripts/host-egress-probe.mjs可复现。 - 链式只覆盖到达本代理的流量。 在
dsh-v0.1.7-alpha.1及之后的宿主上,harness 自身的启动期代理策略与其子进程环境覆盖可能优先于本插件注入的代理名,因此network.upstreamProxy描述的是本代理所处理连接的去向——它不是关于宿主进程每一条出站路径的断言。
与其他 DSH 插件的互操作性
已对照 DSH 0.2.0-rc.2(本 README 面向的运行时)与 2026-10-05 实测的高星插件集验证。
本插件不干扰其他插件,包括广泛安装的高星插件:
- 无工具名冲突。 所有工具都带命名空间,不占用任何已被内置工具或其他插件持有的裸名。
- 无服务键冲突。 只提供
permissionRules,permissionRulesRuntime;该键既不是内置 seam,也没有被任何已调研的高星插件提供。 - 无 slot 冲突。 不注册客户端 slot key,因此不参与
shadows-shipped-ui座位争抢。 - 无 HTTP 路由冲突。 不注册任何
webServer前缀。 - 无 patch 层冲突。 组合包 patch 只
insert自己那一行,从不覆写内置行的config。 - 无全局改写。 不改原型、不改写
process.env、不替换全局 fetch dispatcher。
ctx.on() 监听顺序敏感事件 tools/post-execute, tools/pre-execute —— Cordis 的广播语义:每个监听器都会运行,任何一个都无法饿死其他监听器。此处每个监听器都通过 next() 委托,因此链条绝不会被短路;改写作用在 next() 产出的值上,而不是用它顶替返回:
tools/post-execute— also used bycc-safety-net(1576★).tools/pre-execute— also used bycc-safety-net(1576★).
dsh-plugin-doctor 的 K10–K13 在本仓全部为 pass。
与 dsh-auto-review 协作
dsh-permission-rules产出ask;dsh-auto-review在approval/requestwaterfall 上以只读第二模型裁决作答(或委托给人)。两者都挂载即得完整闭环。- 集成测试:
permissionRules/decision→approval/asked→autoReview/verdict→approval/decided,评审者以脚本化 mock 替换。 - 官方 harness 的
never审批策略与每个失败关闭保证保持不变。
会话日志修复
在 ignorable 标记出现之前写入的会话日志可能被较新 harness 构建拒绝(SessionFormatUnsupportedError)。随附的 scripts/repair-session-logs.mjs 仅重写目标审计行以携带 ignorable: true,保帧、带备份:
node scripts/repair-session-logs.mjs scan [--home DIR] # 报告外来行,不改任何内容
node scripts/repair-session-logs.mjs repair [--home DIR] [--dry-run]
node scripts/repair-session-logs.mjs strip [--home DIR] [--dry-run]
--home 默认 $DSH_HOME/sessions(或 ~/.dsh/sessions)。工具按规范基名发现每一代日志——session.jsonl、session.v2.jsonl、session.v3.jsonl,各自可选 .zstd 压缩——请按世代选择模式:
- v3(
session.v3.jsonl,0.1.5-alpha线原生写出) —— 读取路径接受已标记的插件行,repair即可。 - v2(
session.v2.jsonl,0.1.3-alpha线写出) ——repair可让写出它的宿主打开日志,但0.1.5-alpha的 v2→v3 迁移连已标记的未分类事件也拒绝:请在升级到0.1.5-alpha宿主之前对 v2 日志执行strip。 - v1(
session.jsonl) ——0.1.3-alpha的 v1→v2 迁移连已标记的未知 v1 事件也拒绝:请在 0.1.3 或更新宿主首次打开日志前执行strip。
兼容性
| 维度 | 状态 |
|---|---|
| Harness | DeepSeek Harness dsh-v0.2.1-alpha.1(2026-09-22 已适配,完整门禁链):其插件配置即新的 live settings 契约——每个字段都以 .volatile() 声明,Loader 向 apply 逐个交付活引用,保存的编辑直接写入运行中的引用、不重挂插件,越界值在写入前即被 schema 拒绝。Schemastery 早于 volatile()(3.18.3 之前)的宿主仍能挂载并运行本插件——字段退化为普通值、live 配置表单不可用——因为该标记是能力探测而非假定存在。本线的 Session.append 仍无法盖章 ignorable 标记(第三参数是 surface-intent 包,信封字段仅用于存量日志读取),故整条 0.2-alpha 线在首次追加前即被预检为未盖章,会话日志审计默认停用——其 append 只读取 sourceEventSeqs/surfaceOp 并冻结信封,没有任何可盖章标记的代码路径;更早的 0.1.7-alpha(2026-09-22 已适配)、0.1.5-rc.2(2026-09-09 已适配)与 0.1.3-alpha 线同样沿用 surface-only 追加签名,且每个 0.2 预发布版都与它们同类(0.2.x 的稳定版交由追加探测判定,因此恢复盖章能力无需本插件再发版)。这些线的日志迁移连已标记的未分类插件事件也拒绝:在 0.1.3-alpha 宿主打开日志前 strip 掉 v1 审计行,在 0.1.5-alpha 宿主迁移前 strip 掉 v2 审计行(v3 原生日志只需 repair)。 |
| Node | ^22.19.0 || >=24.9.0 |
| Platforms | 全部(host + Web 设置客户端) |
| Model | 任意(deny/ask 原因经工具结果呈现) |
生态与质量
- Gitee 镜像(同步镜像,以 GitHub 为准)
- dshfind 插件页(安装量与排名)
- OpenSSF Scorecard 报告(由 .github/workflows/scorecard.yml 驱动)
- dsh-plugin-doctor 验证报告(K10–K13 全
pass) - DSH Market(已上架)
- 1024 商店渠道:先
npm i -g dsh1024,再dsh1024 plugin --profile web add dsh-permission-rules(计入 deepseek1024.com 安装排行) - 生态实测知识库:插件开发指南 · 选型实测数据 · 维护取舍判据
开发
pnpm install # node ^22.19 || >=24.9
pnpm run typecheck # tsc, src + tests
pnpm run lint # eslint, src + tests + scripts
pnpm test # vitest: 24 spec files
pnpm run test:coverage # coverage gate (90/80/90/90)
pnpm run build # tsc declarations + tsdown bundles (lib/)
pnpm run pack:check # build + pack (the published artifact)
node scripts/check-readme-sync.mjs # 五语 README 一致性门(CI 同款)
无头端到端验证记录见 VERIFICATION.md。README 配图由 scripts/gen-readme-assets.py 程序化生成(Pillow 绘制 1440×576 中英深浅双版 hero,手写 1100×660 双通道结构 SVG),可重复执行。
Topics:dsh, dsh-plugin, deepseek-harness, permission, policy, allow-deny-ask, approval, safety, network, network-policy, proxy
家族与致谢
本项目是 PerryLink 维护的 DeepSeek Harness 插件家族成员(全部 Apache-2.0)。如果这个插件帮到了你,给个 star——它不解锁任何功能,但会让下一个人更容易找到它。
- @PerryLink —— 创建者与维护者:规则词汇与求值、运行时、HMR 监听、会话日志审计、网络策略 + 代理,以及五语文档。
- @am-i-dead —— 把客户端安全的 allow-host helper 从 host-only 模块中拆出(#24)。
- @22xuan —— 关于 rc.6 宿主静默丢弃审计事件
ignorable标记的详细报告(#2)与上游 harness 讨论;v0.4.1 的运行时宿主能力检测与文档更正直接源自该分析。 - @sjh9714 —— 提出共享规则语法测试向量语料(#4、#5),已于 v0.5.1 以
docs/rule-test-vectors/落地,并在方案讨论中补充了 AST 分解的边界用例。 - @weipeng1999 —— 提出基于 AST 的命令分解功能(#8),促成该方案讨论。
- @alexchenzl —— DSH 目录收录请求(#7)。
- @zl190 —— 报告并验证了
0.1.0-rc.7harness 兼容性缺口(PR #9)。 - @cuohua —— 报告版本门仅覆盖
0.1.0线后,0.1.1-rc线仍静默丢弃ignorable标记(#11);加宽后的版本门直接源自该分析。
展开全部插件
| 插件 | 状态 | |---|---| | dsh-aqua-input-check | | | dsh-archive-check | | | dsh-auto-review | | | dsh-autotier | 🧊 已冻结 — 见仓库 README | | dsh-bid-ca-precheck | | | dsh-bid-qual-check | | | dsh-cert-mcp | 🧊 已冻结 — 见仓库 README | | dsh-checkpoint-rewind | | | dsh-click | | | dsh-composer-history | | | dsh-contract-stance | | | dsh-customs-doc-check | | | dsh-data-quality | 🧊 已冻结 — 见仓库 README | | dsh-demurrage-ledger | | | dsh-doublecheck | | | dsh-drill-script-check | | | dsh-eia-guide-check | | | dsh-emergency-plan | | | dsh-essay-rubric-check | | | dsh-evidence-check | | | dsh-export-ctl-check | | | dsh-fast | | | dsh-fmea-table-check | | | dsh-forecast-penalty | | | dsh-fund-research | | | dsh-github | | | dsh-gongwen-flow-check | | | dsh-gongwen-word-check | | | dsh-guard-plan-qc | | | dsh-hazchem-check | | | dsh-hazplan-check | | | dsh-hidden-risk-map | | | dsh-hs-classify | | | dsh-icd-rule-check | | | dsh-industry-research | | | dsh-lawcite-adapter | | | dsh-laya | | | dsh-lc-doc-check | | | dsh-learning-gap-check | | | dsh-library | | | dsh-local-ai | | | dsh-lsp-actions | | | dsh-mask | | | dsh-mcp-panel | | | dsh-medrec-qc | | | dsh-memento | 🧊 已冻结 — 见仓库 README | | dsh-nsfc-form-check | | | dsh-nurse-record-check | | | dsh-observe | | | dsh-origin-rvc-check | | | dsh-ota-review-check | | | dsh-output-styles | | | dsh-paper-doc-adapter | | | dsh-permission-rules | | | dsh-permit-report-check | | | dsh-pipeline-check | | | dsh-pleading-draft | | | dsh-plugin-doctor | 🚫 已退役(仓库已归档) | | dsh-plugin-guide | | | dsh-plugin-kit | 🚫 已退役(仓库已归档) | | dsh-plugin-upgrade | 🚫 已退役(仓库已归档) | | dsh-policy-brief-draft | | | dsh-power-loss-split | | | dsh-power-ticket-check | | | dsh-ppap-check | | | dsh-protest-deadline | | | dsh-railway-window | | | dsh-repair-order-qc | | | dsh-research-report | | | dsh-review-reply-check | | | dsh-rulefile-check | | | dsh-safety-brief-check | | | dsh-score | 🧊 已冻结 — 见仓库 README | | dsh-session-sync | | | dsh-site-log-check | | | dsh-skill-pack-security | | | dsh-soe-decision-check | | | dsh-soilwater-check | | | dsh-sop-sync-check | | | dsh-spc-gbt-adapter | | | dsh-talk | | | dsh-tender-extract | | | dsh-tender-matrix | | | dsh-test-drive | | | dsh-ticktick | 🚫 已退役(仓库已归档) | | dsh-translate | | | dsh-warranty-calc | | | dsh-budget | 🧊 已冻结 — 见仓库 README | | dsh-claude-move | 🧊 已冻结 — 见仓库 README | | dsh-defend | 🧊 已冻结 — 见仓库 README | | dsh-draw | 🧊 已冻结 — 见仓库 README | | dsh-reach | 🧊 已冻结 — 见仓库 README | | dsh-background-agents | 🚫 已退役(仓库已归档) | | dsh-session-pin | 🚫 已退役(仓库已归档) | | dsh-team-rooms | 🚫 已退役(仓库已归档) |
License
LICENSE(Apache License 2.0)© 2026 dsh-permission-rules contributors
Apache-2.0 · 社区插件,与 DeepSeek 无关。