dsh-perm-gate 0.2.1-beta.2 → 0.2.1-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.ja.md +35 -1
- package/CHANGELOG.ko.md +34 -1
- package/CHANGELOG.md +60 -2
- package/INSTALL.ja.md +18 -3
- package/INSTALL.ko.md +18 -3
- package/INSTALL.md +17 -3
- package/INSTALL.zh.md +16 -3
- package/README.ja.md +59 -8
- package/README.ko.md +58 -8
- package/README.md +58 -22
- package/README.zh.md +44 -18
- package/lib/client.js +27 -0
- package/lib/client.js.map +1 -1
- package/lib/config.d.ts +16 -0
- package/lib/config.js +6 -0
- package/lib/index.d.ts +32 -6
- package/lib/index.js +79 -36
- package/lib/runtime.d.ts +43 -0
- package/lib/runtime.js +123 -0
- package/package.json +17 -8
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
- [日本語 changelog](./CHANGELOG.ja.md)
|
|
13
13
|
- [한국어 changelog](./CHANGELOG.ko.md)
|
|
14
14
|
|
|
15
|
-
> **Compatibility note:** v0.1.
|
|
15
|
+
> **Compatibility note:** v0.2.1-beta.3 ships `ja` / `ko` dictionaries, but official DSH exposes
|
|
16
16
|
> only `zh` / `en` through `LocaleRuntime` (`LOCALE_IDS = ["zh", "en"]`). On stock DSH,
|
|
17
17
|
> selecting `ja` / `ko` fails with `locale "<id>" is not registered`. Use a DSH fork that
|
|
18
18
|
> updates `LOCALE_IDS` (locale-settings.ts) and `LOCALES` labels (client/index.ts), then
|
|
@@ -20,21 +20,24 @@
|
|
|
20
20
|
|
|
21
21
|
> **▼ DSH version compatibility**
|
|
22
22
|
>
|
|
23
|
-
>
|
|
24
|
-
>
|
|
25
|
-
> | 0.1.0-rc.7 ~ 0.1.1-rc.x | ✅ | `ctx.settings.register(ns, schema, { base })` | ✅ `tools/pre-execute` identical | ✅ type-only imports |
|
|
26
|
-
> | 0.1.2-alpha.2+ / 0.1.2-rc.1 | ✅ | `register` still present (`installSection` added) | ✅ `tools/pre-execute` identical | ✅ type-only imports |
|
|
23
|
+
> Two DSH lines are served from two long-lived branches, each with its own version
|
|
24
|
+
> series, `engines.dsh`, and npm dist-tag ([release layout](./RELEASING.md)):
|
|
27
25
|
>
|
|
28
|
-
>
|
|
29
|
-
>
|
|
30
|
-
>
|
|
31
|
-
>
|
|
32
|
-
>
|
|
33
|
-
>
|
|
34
|
-
>
|
|
35
|
-
>
|
|
26
|
+
> | DSH version | Branch | Version | npm tag |
|
|
27
|
+
> | --- | --- | --- | --- |
|
|
28
|
+
> | 0.1.0-rc.7 ~ 0.1.1-rc.x | `legacy` | `1.x` | `@legacy` |
|
|
29
|
+
> | 0.1.2-alpha.1+ (incl. 0.1.5-rc.2) | `main` | `0.2.x` | `@latest` |
|
|
30
|
+
>
|
|
31
|
+
> `@deepseek-ai/dsh-client-runtime` was **removed** at `0.1.2-alpha.1` — it did not
|
|
32
|
+
> merely move. The `legacy` line still reaches `ctx.slots` through it; `main` gets
|
|
33
|
+
> the same declaration from `@deepseek-ai/dsh-client-ui-renderer/client`. Two
|
|
34
|
+
> version-sensitive seams are handled by capability probes rather than version
|
|
35
|
+
> checks: (1) settings registration uses `register`, which exists on both lines
|
|
36
|
+
> (`installSection` is an addition, not a replacement); (2) `effectivePolicy` is a
|
|
37
|
+
> **private** method of the user-approval service on both, so it is read behind a
|
|
38
|
+
> `typeof` probe and degrades to “policy unknown” when absent or throwing.
|
|
36
39
|
|
|
37
|
-
Version **0.1.
|
|
40
|
+
Version **0.2.1-beta.3** — see the [Changelog](./CHANGELOG.md).
|
|
38
41
|
|
|
39
42
|
A single, self-sufficient, deterministic-first, fail-closed permission gate for DeepSeek Harness.
|
|
40
43
|
|
|
@@ -71,8 +74,12 @@ cross-plugin version coupling.
|
|
|
71
74
|
model-visible reason matches the recorded outcome.
|
|
72
75
|
- **Permissive tier** — an **independent approval mode** (separate from read-only, full-access
|
|
73
76
|
and whitelist tiers) that is neither "auto-approve" nor blanket trust. Front-end exposes a
|
|
74
|
-
**single switch** (`permissive`); the
|
|
77
|
+
**single switch** (`permissive`); the four backend strategies are **combinable** and driven
|
|
75
78
|
by plugin settings — still fail-closed against P0.
|
|
79
|
+
- **Sandbox-escalation auto-answer** (`trustEscalation`) — a sandbox escalation is asked from
|
|
80
|
+
*inside* the shell / pwsh / edit tool body, after `tools/pre-execute`, so the gate never saw
|
|
81
|
+
it and a call it auto-allowed still prompted you to approve the widening. With this strategy
|
|
82
|
+
on, the exact call the gate cleared (matched by `callId`) is answered here instead.
|
|
76
83
|
- **Risk-graded `llmAssist`** — a custom OpenAI-compatible LLM grades each `ask` as
|
|
77
84
|
`safe` / `risky:<category>`; hard categories (deletion, credential, remote, system, bulk)
|
|
78
85
|
**always ask**, neutral enters verdict learning, and every failure stays fail-closed.
|
|
@@ -161,6 +168,7 @@ In `cordis.yml`:
|
|
|
161
168
|
trustAutoAllow: true # in-scope safe ops auto-allow; dangerous/unknown ask
|
|
162
169
|
alwaysConfirm: false # every crossing asks; allow-controls add repeat-allow / wl-migrate buttons
|
|
163
170
|
llmAssist: false # LLM classify first, human fallback on ask/failure
|
|
171
|
+
trustEscalation: true # a cleared call's own sandbox escalation needs no prompt
|
|
164
172
|
```
|
|
165
173
|
|
|
166
174
|
`trustAutoAllow` is the baseline middle tier (rule-allow auto-passes). `alwaysConfirm` surfaces
|
|
@@ -169,22 +177,50 @@ the approval panel for every crossing; its "allow controls" add two extended but
|
|
|
169
177
|
(which persists the command word into the `permissions.yaml` allow whitelist via
|
|
170
178
|
`approveAllowEverywhere`). `llmAssist` consults a real, configurable LLM (`classifierEndpoint` /
|
|
171
179
|
`classifierModel`, any OpenAI-compatible API) to auto-decide an `ask`, and falls back to the
|
|
172
|
-
human seam on `ask`/error — always fail-closed.
|
|
173
|
-
|
|
180
|
+
human seam on `ask`/error — always fail-closed. `trustEscalation` (on by default while the tier
|
|
181
|
+
is on) answers a `sandbox_permissions` escalation raised from inside a call the gate already
|
|
182
|
+
allowed; see below. When `permissive` is off, the gate behaves exactly as before.
|
|
183
|
+
|
|
184
|
+
### Sandbox escalation: why a `safe` verdict still prompted
|
|
185
|
+
|
|
186
|
+
A tool call can raise **two independent approvals**. The gate owns the first — its own `ask`, on
|
|
187
|
+
the `tools/pre-execute` waterfall. The second comes from `approveEscalation` **inside the tool
|
|
188
|
+
body**, at `tools/execute` time, whenever the model passed `sandbox_permissions` +
|
|
189
|
+
`justification`; by then `tools/pre-execute` has already settled, so the gate's allow never
|
|
190
|
+
reaches it. A call the LLM graded `safe` and the gate auto-allowed therefore still showed a
|
|
191
|
+
prompt asking you to approve the sandbox widening.
|
|
192
|
+
|
|
193
|
+
`trustEscalation` closes that gap. The gate remembers every call it positively allowed (keyed by
|
|
194
|
+
the host's `callId`, which the escalation request repeats) and answers the escalation
|
|
195
|
+
`allowed-once` itself. It applies only when *all* hold:
|
|
196
|
+
|
|
197
|
+
- the Permissive tier is on and `trustEscalation` is on;
|
|
198
|
+
- the request carries a `callId` the gate cleared, with a matching tool name;
|
|
199
|
+
- the reason is a recognized escalation naming `workspace-write` or `danger-full-access`.
|
|
200
|
+
|
|
201
|
+
Everything else — an unrecognized reason, a different call, a call the gate asked or denied, the
|
|
202
|
+
`approval: never` passthrough — delegates to the human unchanged, so a future DSH wording change
|
|
203
|
+
fails closed rather than open. The auto-answer is recorded on the event feed
|
|
204
|
+
(`verdict: "escalation-auto"`, `mode: <target>`). Turn the switch off to keep widening
|
|
205
|
+
human-gated while other allows stay automatic.
|
|
206
|
+
|
|
174
207
|
|
|
175
208
|
### Risk-graded llmAssist, verdict learning, and the event feed
|
|
176
209
|
|
|
177
210
|
When `llmAssist` is on, the configured LLM grades one `ask` at a time with a structured
|
|
178
|
-
protocol.
|
|
211
|
+
protocol. Grading happens **inside the gate's `tools/pre-execute` waterfall, before the decision
|
|
212
|
+
is returned to the host**: a `safe` verdict delegates the call straight through, so the approval
|
|
213
|
+
panel never appears; only a genuinely uncertain verdict reaches you. Two receiver sources are
|
|
214
|
+
selectable in the settings card: a **custom API** (any
|
|
179
215
|
OpenAI-compatible endpoint — `classifierEndpoint` / `classifierModel` / `classifierApiKey`,
|
|
180
216
|
with presets including Xiaomi MiMo `https://api.xiaomimimo.com/v1`), or the **DSH host model
|
|
181
217
|
group** (the session's configured `llm` service, via `agentDefaultModel.currentSelection`,
|
|
182
218
|
optionally overridden with `classifierProvider` / `classifierModel`). A **health test** button
|
|
183
219
|
(`POST /api/dsh-perm-gate/health`) runs one minimal completion and reports latency.
|
|
184
220
|
|
|
185
|
-
- `safe` → the
|
|
186
|
-
- `risky` + a **hard category** (`deletion`, `credential`, `remote`, `system`, `bulk`) →
|
|
187
|
-
|
|
221
|
+
- `safe` → the call is auto-allowed (audited as the `classifier` source); no panel is shown.
|
|
222
|
+
- `risky` + a **hard category** (`deletion`, `credential`, `remote`, `system`, `bulk`) → the call
|
|
223
|
+
is **auto-denied** without a panel; hard risks are never auto-allowed and never learned.
|
|
188
224
|
- `risky:neutral` → with `riskLearning` enabled (Settings card, off by default), each human
|
|
189
225
|
approval that actually executes (settled via the host's `tools/result` event) counts toward
|
|
190
226
|
a `tool|category` key; once the count reaches `riskThreshold` (default 3) **and** the new
|
|
@@ -245,7 +281,7 @@ session's effective approval policy is `never`.
|
|
|
245
281
|
|
|
246
282
|
The tier is also adjustable at runtime from **Settings → Plugins → Permissive approval tier**
|
|
247
283
|
(a `settings.plugins.tab` page rendered by the plugin's browser client): one switch toggles
|
|
248
|
-
`permissive`, and
|
|
284
|
+
`permissive`, and four toggles edit the backend `permissiveStrategies`. The host reads the
|
|
249
285
|
namespace live, so a change applies to the next tool call without a restart. This is an
|
|
250
286
|
independent approval class, NOT the DSH "auto-approval" mode.
|
|
251
287
|
|
package/README.zh.md
CHANGED
|
@@ -12,26 +12,30 @@
|
|
|
12
12
|
- [日本語 changelog](./CHANGELOG.ja.md)
|
|
13
13
|
- [한국어 changelog](./CHANGELOG.ko.md)
|
|
14
14
|
|
|
15
|
-
> **兼容性说明:** v0.1.
|
|
15
|
+
> **兼容性说明:** v0.2.1-beta.3 自带 `ja` / `ko` 字典,但官方 DSH 的 `LocaleRuntime`
|
|
16
16
|
> 只暴露 `zh` / `en`(`LOCALE_IDS = ["zh", "en"]`)。在原版 DSH 上选择 `ja` / `ko`
|
|
17
17
|
> 会报 `locale "<id>" is not registered`。请使用更新了 `LOCALE_IDS`
|
|
18
18
|
> (locale-settings.ts)与 `LOCALES` 标签(client/index.ts)的 DSH fork 并重新构建。
|
|
19
19
|
|
|
20
20
|
> **▼ DSH 版本适配**
|
|
21
21
|
>
|
|
22
|
-
>
|
|
23
|
-
>
|
|
24
|
-
> | 0.1.0-rc.7 ~ 0.1.1-rc.x | ✅ | `ctx.settings.register(ns, schema, { base })` | ✅ `tools/pre-execute` 一致 | ✅ 仅类型导入 |
|
|
25
|
-
> | 0.1.2-alpha.2+ / 0.1.2-rc.1 | ✅ | `register` 仍保留(另加 `installSection`) | ✅ `tools/pre-execute` 一致 | ✅ 仅类型导入 |
|
|
22
|
+
> 两个 DSH 版本线从两个长期分支分别维护,各有一套版本号系列、`engines.dsh`
|
|
23
|
+
> 和 npm 分发标签([发布布局](./RELEASING.md)):
|
|
26
24
|
>
|
|
27
|
-
>
|
|
28
|
-
>
|
|
29
|
-
>
|
|
30
|
-
>
|
|
31
|
-
>
|
|
32
|
-
>
|
|
25
|
+
> | DSH 版本 | 分支 | 版本号 | npm 标签 |
|
|
26
|
+
> | --- | --- | --- | --- |
|
|
27
|
+
> | 0.1.0-rc.7 ~ 0.1.1-rc.x | `legacy` | `1.x` | `@legacy` |
|
|
28
|
+
> | 0.1.2-alpha.1+(含 0.1.5-rc.2) | `main` | `0.2.x` | `@latest` |
|
|
29
|
+
>
|
|
30
|
+
> `@deepseek-ai/dsh-client-runtime` 在 `0.1.2-alpha.1` 中已被**移除**——不仅仅是更名。
|
|
31
|
+
> `legacy` 线仍通过它访问 `ctx.slots`;`main` 从
|
|
32
|
+
> `@deepseek-ai/dsh-client-ui-renderer/client` 获得相同的声明。两处版本敏感
|
|
33
|
+
> 接缝通过**能力探测**处理,而非版本号检查:(1)设置注册使用 `register`,两线
|
|
34
|
+
> 都存在(`installSection` 是新增项,不是替代);(2)`effectivePolicy` 在两
|
|
35
|
+
> 线上都是 user-approval 服务的**私有**方法,因此通过 `typeof` 探测读取,缺失
|
|
36
|
+
> 或抛错时降级为「策略未知」。
|
|
33
37
|
|
|
34
|
-
版本 **0.1.
|
|
38
|
+
版本 **0.2.1-beta.3** —— 变更见 [Changelog](./CHANGELOG.md)。
|
|
35
39
|
|
|
36
40
|
一个**单一自足、确定性优先、fail-closed** 的 DeepSeek Harness 权限门插件。
|
|
37
41
|
|
|
@@ -54,7 +58,8 @@
|
|
|
54
58
|
- **会话放行** — 精确的 `(工具, 规范化 fingerprint)` grant,带 `TTL` + `maxUses`;换目标绝不复用。子代理继承但不可自授。
|
|
55
59
|
- **纯函数规则引擎** — glob/regex 编译 + ReDoS 上限、坏规则 loud fail、按源内容哈希缓存。
|
|
56
60
|
- **审计** — 每次决策写为 `{ignorable:true}` 事件并带 `callId`;模型可见理由与记录一致。
|
|
57
|
-
- **Permissive 档位** — 一个**独立审批模式**(区别于只读、完全权限与白名单档),既不是"自动审批",也不授予泛化权限。前端只暴露**一个开关**(`permissive
|
|
61
|
+
- **Permissive 档位** — 一个**独立审批模式**(区别于只读、完全权限与白名单档),既不是"自动审批",也不授予泛化权限。前端只暴露**一个开关**(`permissive`),后台四个审批策略**可组合**、由插件设置决定——仍对 P0 保持 fail-closed。
|
|
62
|
+
- **沙箱提权自动答复**(`trustEscalation`)— 沙箱提权是从 shell / pwsh / edit 工具**体内部**(`tools/pre-execute` 之后)发出的,所以门禁从未见过它,一个它自动放行的调用仍会弹出确认。开启后,门禁以 `callId` 精确匹配已放行调用并直接答复。
|
|
58
63
|
|
|
59
64
|
## 安装
|
|
60
65
|
|
|
@@ -101,6 +106,7 @@ P0 硬拒绝始终单调且不可协商。
|
|
|
101
106
|
permissiveStrategies: # 后台策略,可组合
|
|
102
107
|
trustAutoAllow: true # 作用域内安全操作自动放行;危险/未知转 ask
|
|
103
108
|
alwaysConfirm: false # 一律逐次 ask;允许控件附带重复允许/迁白名单按钮
|
|
109
|
+
trustEscalation: true # 门禁已放行的调用,其自身的沙箱提权免确认
|
|
104
110
|
llmAssist: false # 先由 LLM 分类裁决;ask/无分类器时回退到人工
|
|
105
111
|
```
|
|
106
112
|
(llmAssist 的真实接收 LLM 在设置页填 `classifierEndpoint` / `classifierModel`,OpenAI 兼容的自定义 API
|
|
@@ -110,7 +116,27 @@ P0 硬拒绝始终单调且不可协商。
|
|
|
110
116
|
「允许控件」含两个扩展按钮:**本会话重复允许该类**(会话限次 grant,`approveRepeat`)与
|
|
111
117
|
**允许所有类型**(把命令词持久写进 `permissions.yaml` 的 allow 白名单,`approveAllowEverywhere`)。
|
|
112
118
|
`llmAssist` 调用配置的真实 LLM(任意 OpenAI 兼容 API)自动裁决 `ask`,结果不确定/出错时回退人工
|
|
113
|
-
接缝——始终 fail-closed。`
|
|
119
|
+
接缝——始终 fail-closed。`trustEscalation`(档位开启时默认开)答复门禁已放行的调用在其工具体内
|
|
120
|
+
提出的 `sandbox_permissions` 提权;见下文。`permissive` 关闭时,门禁行为与之前完全一致。
|
|
121
|
+
|
|
122
|
+
### 沙箱提权:为何 `safe` 裁决仍会弹窗
|
|
123
|
+
|
|
124
|
+
一个工具调用可能触发**两个独立的审批**。门禁负责第一个——它的 `ask`,在 `tools/pre-execute`
|
|
125
|
+
瀑布上。第二个来自工具体内部的 `approveEscalation`,在 `tools/execute` 时刻,只要模型传了
|
|
126
|
+
`sandbox_permissions` + `justification`;此时 `tools/pre-execute` 已结算,门禁的放行从未到达它。
|
|
127
|
+
LLM 评定为 `safe` 且门禁自动放行的调用因此仍会弹出确认。
|
|
128
|
+
|
|
129
|
+
`trustEscalation` 填补这个缺口。门禁记住每个它正面向上放行的调用(以宿主 `callId` 为键,提权
|
|
130
|
+
请求会重复该值),并在本处自行答复 `allowed-once`。它仅在**全部满足**时适用:
|
|
131
|
+
|
|
132
|
+
- Permissive 档位开启且 `trustEscalation` 开启;
|
|
133
|
+
- 请求携带门禁放行的 `callId`,且工具名匹配;
|
|
134
|
+
- 原因为已知的提权,指明 `workspace-write` 或 `danger-full-access`。
|
|
135
|
+
|
|
136
|
+
其余所有情况——未知原因、不同的调用、门禁要求或拒绝的调用、`approval: never` 透传——都保持交给人
|
|
137
|
+
工,因此未来 DSH 措辞变更时 fail-closed。自动答复记录在事件流中
|
|
138
|
+
(`verdict: "escalation-auto"`,`mode: <目标模式>`)。关闭开关可使沙箱放宽保持人工审批,其余
|
|
139
|
+
自动放行不变。
|
|
114
140
|
|
|
115
141
|
### 权限下拉里可选档位
|
|
116
142
|
|
|
@@ -132,16 +158,16 @@ Full access 之间。DSH 的 bundle patch 对这个 map 是**整表替换**而
|
|
|
132
158
|
### 在 UI 里可配置
|
|
133
159
|
|
|
134
160
|
该档位也可在运行时从 **设置 → 插件 → Permissive 审批档** 调整(插件浏览器端渲染的
|
|
135
|
-
`settings.plugins.tab` 页面):一个开关切换 `permissive
|
|
161
|
+
`settings.plugins.tab` 页面):一个开关切换 `permissive`,四个开关编辑后台
|
|
136
162
|
`permissiveStrategies`。host 端 live 读取该命名空间,改动对下一条工具调用即时生效,无需重启。
|
|
137
163
|
这是一个独立审批类,**不是** DSH 的"auto-approval"档。
|
|
138
164
|
|
|
139
165
|
### 风险分级 llmAssist、裁决学习与事件流
|
|
140
166
|
|
|
141
|
-
开启 `llmAssist` 后,接收 LLM(自定义 OpenAI 兼容端点,或 DSH 宿主模型组——见上文)按结构化协议逐条评估 `ask
|
|
167
|
+
开启 `llmAssist` 后,接收 LLM(自定义 OpenAI 兼容端点,或 DSH 宿主模型组——见上文)按结构化协议逐条评估 `ask`。**判定发生在门禁的 `tools/pre-execute` 瀑布内部、决策返回宿主之前**:`safe` 直接放行,审批面板根本不会出现;只有真正无法确定的判定才会弹到你面前。
|
|
142
168
|
|
|
143
|
-
- `safe` → 自动放行(审计来源为 `classifier
|
|
144
|
-
- `risky` + **硬风险类别**(`deletion`、`credential`、`remote`、`system`、`bulk`)→
|
|
169
|
+
- `safe` → 自动放行(审计来源为 `classifier`),不弹面板。
|
|
170
|
+
- `risky` + **硬风险类别**(`deletion`、`credential`、`remote`、`system`、`bulk`)→ **自动拒绝**、不弹面板;硬风险永不自动放行、也永不进入学习。
|
|
145
171
|
- `risky:neutral` → 若开启 `riskLearning`(设置卡片内,默认关闭),人工批准且真实执行的 neutral 风险会按 `tool|类别` 计数;计数达到 `riskThreshold`(默认 3)且新调用的操作指纹(命令词 + 目标基名)命中已确认样本时,**同一操作**自动放行。不同目标永不复用该放行。开启学习沉淀(`riskSediment`,默认开)后,满阈值 key 的确认样本会成为**确定性放行规则**:指纹精确命中即直接放行、无需再过 LLM——即使关闭 llmAssist 也继续生效;沉淀规则在设置卡片中可见、可管理(终止学习 / 删除样本)。
|
|
146
172
|
- 超时(`riskTimeoutMs`,默认 20s,重试 1 次)、传输失败与协议外输出均维持原 `ask`——门禁绝不猜测。
|
|
147
173
|
|
package/lib/client.js
CHANGED
|
@@ -20,6 +20,8 @@ window.__ModuleLoader__.load({
|
|
|
20
20
|
"card.strategy.trustAutoAllow": "trustAutoAllow — 作用域内安全操作自动放行,危险/未知转 ask(中间档基线)",
|
|
21
21
|
"card.strategy.alwaysConfirm": "alwaysConfirm — 一律逐次 ask;审批面板「允许控件」含两个扩展按钮:「本会话重复允许该类」(会话语限次 grant)与「允许所有类型」(命令词持久迁入 rulesFile 白名单)",
|
|
22
22
|
"card.strategy.llmAssist": "llmAssist — 自定义 LLM 按风险分级裁决:safe 自动放行;deletion/credential/remote/system/bulk 硬风险自动拒绝;neutral 进入确认学习;失败/超时回退人工",
|
|
23
|
+
"card.strategy.trustEscalation": "trustEscalation — 沙箱升级免确认:本门禁已放行的调用,其工具内部发起的沙箱提权(shell / pwsh / edit 的 sandbox_permissions)由门禁直接批准,不再弹窗",
|
|
24
|
+
"card.strategy.trustEscalationHint": "沙箱提权审批发生在 tools/pre-execute 之后、工具体内部,门禁原本看不到它,因此「LLM 判安全已自动放行」的调用仍会弹窗要求你批准提权。开启后,仅对门禁确实放行过的那一次调用(按 callId 精确匹配)免确认,其余一律照旧走人工;目标模式非 workspace-write / danger-full-access 或理由无法识别时同样回退人工。关闭后提权保持人工把关。",
|
|
23
25
|
"card.readonly": "只读",
|
|
24
26
|
"card.unavailable": "设置命名空间不可用:请确认 dsh-perm-gate 已装配进 profile。",
|
|
25
27
|
"card.llmReceiver": "llmAssist 接收 LLM(OpenAI 兼容,可用自定义 API)",
|
|
@@ -127,6 +129,8 @@ window.__ModuleLoader__.load({
|
|
|
127
129
|
"card.strategy.trustAutoAllow": "trustAutoAllow — safe in-scope ops auto-allow; dangerous/unknown ask (baseline middle tier)",
|
|
128
130
|
"card.strategy.alwaysConfirm": "alwaysConfirm — every crossing asks; the approval \"allow controls\" get two extended buttons: \"repeat-allow this type this session\" (bounded session grant) and \"allow every occurrence\" (persist the command word into the rulesFile whitelist)",
|
|
129
131
|
"card.strategy.llmAssist": "llmAssist — a custom LLM grades risk: safe auto-allows; deletion/credential/remote/system/bulk hard risks auto-deny; neutral enters confirm-learning; failure/timeout falls back to the human",
|
|
132
|
+
"card.strategy.trustEscalation": "trustEscalation — sandbox escalation without a prompt: for a call this gate already allowed, the sandbox widening a shell / pwsh / edit tool raises from inside itself is approved here instead of asking you",
|
|
133
|
+
"card.strategy.trustEscalationHint": "A sandbox escalation is asked from inside the tool body, after tools/pre-execute, so the gate never saw it — a call the LLM graded safe and the gate auto-allowed still prompted you to approve the widening. With this on, only the exact call the gate allowed (matched by callId) skips the prompt; everything else goes to the human as before, as does any unrecognized reason or a target other than workspace-write / danger-full-access. Turn it off to keep widening human-gated.",
|
|
130
134
|
"card.readonly": "Read-only",
|
|
131
135
|
"card.unavailable": "Settings namespace unavailable: make sure dsh-perm-gate is assembled into this profile.",
|
|
132
136
|
"card.llmReceiver": "llmAssist receiving LLM (OpenAI-compatible; any custom API)",
|
|
@@ -742,6 +746,29 @@ window.__ModuleLoader__.load({
|
|
|
742
746
|
}
|
|
743
747
|
})]
|
|
744
748
|
}),
|
|
749
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
750
|
+
style: rowStyle,
|
|
751
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
752
|
+
htmlFor: "plugin-config-perm-gate-escalation",
|
|
753
|
+
style: { fontSize: "12px" },
|
|
754
|
+
children: t("card.strategy.trustEscalation")
|
|
755
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
756
|
+
id: "plugin-config-perm-gate-escalation",
|
|
757
|
+
type: "checkbox",
|
|
758
|
+
checked: strategies.trustEscalation ?? true,
|
|
759
|
+
disabled: readonly || !effective,
|
|
760
|
+
onChange: (event) => {
|
|
761
|
+
scope.set("permissiveStrategies", {
|
|
762
|
+
...strategies,
|
|
763
|
+
trustEscalation: event.currentTarget.checked
|
|
764
|
+
});
|
|
765
|
+
}
|
|
766
|
+
})]
|
|
767
|
+
}),
|
|
768
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
769
|
+
style: hintStyle,
|
|
770
|
+
children: t("card.strategy.trustEscalationHint")
|
|
771
|
+
}),
|
|
745
772
|
strategies.llmAssist === true ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
746
773
|
style: sectionStyle,
|
|
747
774
|
children: [
|