dsh-perm-gate 5.4.3 → 5.4.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.md +5 -0
- package/README.md +26 -0
- package/dsh.plugin.json +1 -1
- package/lib/ask-context.d.ts +19 -0
- package/lib/ask-context.js +58 -9
- package/lib/client.js +35 -0
- package/lib/client.js.map +1 -1
- package/lib/config.d.ts +20 -1
- package/lib/config.js +8 -1
- package/lib/index.js +3 -0
- package/lib/runtime.d.ts +18 -0
- package/lib/runtime.js +41 -4
- package/lib/workspace-bound.d.ts +7 -0
- package/lib/workspace-bound.js +48 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 5.4.4 (2026-11-03)
|
|
6
|
+
|
|
7
|
+
- **YOLO 工作区豁免开关 `yoloWorkspaceExempt`(默认关)**:`opaque` 拆成两类——`consequence`(执行内容看不见:编码载荷、正文读不到的脚本、prose)与 `location`(动作本身可见,只是落点判不清:无参数工具、工作区外未读到正文的脚本)。开关只在 `permissive-yolo` 一档上跳过 `location` 那一条,且要求目标全部落在 workspace 内、非删除/非远端写、非不可逆/不可沉淀;`consequence` 与 P0/凭据/`irreversible`/`neverClear` 一律不变。工作区边界的判定在运行时另走 `pathsRealInsideWorkspace`(`node:fs` realpath,Windows 折叠大小写),符号链接/目录联接指向外部、或路径无法解析时一律不放行;`ask-context` 仍保持无依赖的词法判定供浏览器半复用。无审查模型时被豁免调用直接放行,事件标 `yolo-allow-opaque-location-exempt(-no-reviewer)`,审计 reason 带 `[exempt:opaque-location]`,与「机械网没发现」可区分。其余四档行为零变化,关机即回到 5.4.3 行为。
|
|
8
|
+
- **看不见的脚本体现在真的算 opaque**:`too-large` / `binary` / `unreadable` 的脚本正文一律使调用进入 U 档(此前只有工作区外的脚本会),与 `ask-context` 里「one unreadable file keeps the whole call opaque」的注释一致;`missing` 与 `not-a-file` 故意排除——那里根本不会执行任何东西,放宽才不会被用户当成噪音忽略。
|
|
9
|
+
|
|
5
10
|
## 5.4.3 (2026-11-03)
|
|
6
11
|
|
|
7
12
|
- **#6 fail-open 修复**:宿主把 volatile 字段以**引用**交给 `apply`,此前 `...config` 把引用原样展开进运行时选项;引用对象既不等于 `deny` 也不等于 `ask`,运行时两条分支都落空,未命中任何规则的调用直接放过——即使配的是 ask / 默认审查。现在构造前先 `resolveVolatileConfig` 解引用,`coerceRuleAction` 把非三值一律 fail-closed 成 `ask`(规则文档路径同样过一遍),`defaultAction` / `caseInsensitivePaths` 改由 live 钩子读取并纳入热更新 key,改设置后 `reload()` 生效(此前只有首轮播种,改值不生效)。
|
package/README.md
CHANGED
|
@@ -335,6 +335,7 @@ In `cordis.yml`:
|
|
|
335
335
|
llmAssist: false # LLM classify first, human fallback on ask/failure
|
|
336
336
|
trustEscalation: true # a cleared call's own sandbox escalation needs no prompt
|
|
337
337
|
yolo: false # unattended: never ask a human, block danger, run the rest
|
|
338
|
+
yoloWorkspaceExempt: false # YOLO only: stop treating "target unpinnable" as danger (see below)
|
|
338
339
|
rulesFallback: false # no reviewer available => decide on the rule nets alone
|
|
339
340
|
scriptReview: true # attach the body of a script the call runs to the review
|
|
340
341
|
credentialPaths: [] # long-tail secret paths, held to the `.ssh` standard
|
|
@@ -363,6 +364,31 @@ All five tiers ship in the plugin's own profile patch, so they are in the picker
|
|
|
363
364
|
nothing to hand-edit. Presets outside `gatePresets` never reach any of this: the whole gate
|
|
364
365
|
stands down there, so there is no ask to settle.
|
|
365
366
|
|
|
367
|
+
### `yoloWorkspaceExempt` — the one thing YOLO may stop blocking on
|
|
368
|
+
|
|
369
|
+
Off by default. It relaxes exactly one signal: **the target could not be pinned down**. A call
|
|
370
|
+
whose *content* was never seen is still blocked, so the switch only affects the two shapes where
|
|
371
|
+
the act itself is ordinary and only its location is missing — a tool invoked with no arguments at
|
|
372
|
+
all, and a script outside the workspace whose body was never read.
|
|
373
|
+
|
|
374
|
+
| what was missing | switch off | switch on |
|
|
375
|
+
| --- | --- | --- |
|
|
376
|
+
| no arguments to inspect (e.g. a directory-state tool) | block `opaque-payload` | **run** (reviewed, or mechanically when no reviewer) |
|
|
377
|
+
| script outside the workspace, body not read | block `opaque-payload` | **run** |
|
|
378
|
+
| encoded payload (`-EncodedCommand`, `FromBase64String`, …) | block | **block** |
|
|
379
|
+
| script body attached as unreadable (too large / binary) | block | **block** |
|
|
380
|
+
| script body missing, or the target is a directory (nothing will run) | ordinary layers | **unchanged** |
|
|
381
|
+
| prose with no parseable program | block | **block** |
|
|
382
|
+
| delete / remote write | handled by the ordinary layers | **unchanged** |
|
|
383
|
+
| P0, credentials, `irreversible`/`neverClear` | deny | **unchanged** |
|
|
384
|
+
|
|
385
|
+
Two more preconditions are checked before the signal is skipped: every target the call names must
|
|
386
|
+
resolve inside the workspace, **following links** (a prefix-only match like `/work2` is not `/work`,
|
|
387
|
+
and a link that points outside is refused; a path that cannot be resolved counts as outside), and
|
|
388
|
+
the ordinary write/edit contract must be intact. Only `permissive-yolo` reads the switch; the other
|
|
389
|
+
tiers ignore it. Allowed calls are recorded as `yolo-allow-opaque-location-exempt` (or
|
|
390
|
+
`…-exempt-no-reviewer`), so an exemption can always be told apart from "the screen found nothing".
|
|
391
|
+
|
|
366
392
|
|
|
367
393
|
`trustAutoAllow` is the baseline middle tier (rule-allow auto-passes). `alwaysConfirm` surfaces
|
|
368
394
|
the approval panel for every crossing; its "allow controls" add two extended buttons —
|
package/dsh.plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "dsh-perm-gate",
|
|
3
3
|
"name": "dsh-perm-gate",
|
|
4
|
-
"version": "5.4.
|
|
4
|
+
"version": "5.4.4",
|
|
5
5
|
"description": {
|
|
6
6
|
"en": "Deterministic-first, fail-closed permission gate for DeepSeek Harness 0.1.2+: a P0 hard-deny -> P1 precise session grant -> P2 static allow/deny rule chain -> P3 optional LLM classifier -> P4 ask pipeline over the tools/pre-execute waterfall, with a standalone CLI dry-run evaluator and an auditable decision log. Credential handling is a seven-family ladder (ssh/cloud/package/gitcreds/env/cli/db) with deny/ask/readonly/readwrite rungs kept in the rules document plus a paired write-exemption list; a protected-branch push switch keeps the P0 floor by default. It only vetoes with deny/ask and always delegates otherwise, and unknown or malformed rules fail loud instead of silently standing the gate down.",
|
|
7
7
|
"zh": "面向 DeepSeek Harness 0.1.2+ 的确定性优先、失败即拒的权限闸门:在 tools/pre-execute 瀑布上串起 P0 硬拒绝 → P1 精确会话授权 → P2 静态 allow/deny 规则链 → P3 可选 LLM 语义分类 → P4 ask,并附带独立 CLI 干跑评估器与可审计的决策日志。凭据处理为七族阶梯(ssh/cloud/package/gitcreds/env/cli/db)× deny/ask/readonly/readwrite 四档,档位存规则文档 + 成对写豁免清单;保护分支强推开关默认保留 P0 地板。只以 deny/ask 否决、其余一律放行,规则未知或非法时直接报错,绝不静默失效。"
|
package/lib/ask-context.d.ts
CHANGED
|
@@ -8,6 +8,17 @@ export type Reversibility =
|
|
|
8
8
|
| 'C'
|
|
9
9
|
/** reversible or read-only (list, diff, build, local commit, workspace edit) */
|
|
10
10
|
| 'R';
|
|
11
|
+
/**
|
|
12
|
+
* Why a payload could not be inspected.
|
|
13
|
+
*
|
|
14
|
+
* `consequence` — what will run is invisible (encoded blob, unreadable script body,
|
|
15
|
+
* prose with no parseable program): no tier may treat this as "probably fine".
|
|
16
|
+
* `location` — the act itself is visible and ordinary, only its target could not be
|
|
17
|
+
* pinned down (a bare no-argument call, a script outside the workspace whose body was
|
|
18
|
+
* not read). The distinction exists so a tier can relax the second without ever
|
|
19
|
+
* relaxing the first.
|
|
20
|
+
*/
|
|
21
|
+
export type OpaqueKind = 'location' | 'consequence';
|
|
11
22
|
/** What the call is aimed at. */
|
|
12
23
|
export type TargetKind = 'read' | 'write' | 'delete' | 'remote-write' | 'exec-external' | 'unknown';
|
|
13
24
|
/**
|
|
@@ -73,6 +84,14 @@ export interface AskContext extends AskContextSource {
|
|
|
73
84
|
readonly unlearnable: boolean;
|
|
74
85
|
/** Read-only commands that need no human attention at all. */
|
|
75
86
|
readonly readOnly: boolean;
|
|
87
|
+
/** Set only when `targetResolvable` is false: see {@link OpaqueKind}. */
|
|
88
|
+
readonly opaqueKind?: OpaqueKind;
|
|
89
|
+
/**
|
|
90
|
+
* Whether every target this call names resolves inside `workspaceRoot`.
|
|
91
|
+
* `false`/absent means "cannot prove it stays inside", so a tier that relaxes
|
|
92
|
+
* location-opacity must not use it.
|
|
93
|
+
*/
|
|
94
|
+
readonly workspaceBound?: boolean;
|
|
76
95
|
}
|
|
77
96
|
/**
|
|
78
97
|
* Freeze one call into an {@link AskContext}. Pure and side-effect free: it reads
|
package/lib/ask-context.js
CHANGED
|
@@ -57,6 +57,16 @@ const RECOVERABLE_EXTERNAL = /\b(git\s+push|gh\s+pr\s+create|gh\s+api\b|--method
|
|
|
57
57
|
*/
|
|
58
58
|
/** Encoded or otherwise uninspectable payload. */
|
|
59
59
|
const OPAQUE = /(?:-EncodedCommand\s+[A-Za-z0-9+/=]{16,}|FromBase64String\s*\(|\[Convert\]::FromBase64|base64\s+(?:-d|--decode)|eval\s*\(\s*atob)/i;
|
|
60
|
+
/**
|
|
61
|
+
* "The code exists, and nobody could see it."
|
|
62
|
+
*
|
|
63
|
+
* `missing` and `not-a-file` are deliberately **not** in this set: nothing will execute,
|
|
64
|
+
* so holding the call would only teach people to ignore the gate (measured: `python
|
|
65
|
+
* scripts/build.py` for a file that is simply not there came out `U`). A file that is
|
|
66
|
+
* there but unreadable — too large, binary, permission-denied — is invisible code, and
|
|
67
|
+
* an invisible body keeps the call opaque wherever the script lives.
|
|
68
|
+
*/
|
|
69
|
+
const INVISIBLE_SCRIPT_BODY = new Set(['too-large', 'binary', 'unreadable']);
|
|
60
70
|
/**
|
|
61
71
|
* A command segment whose head cannot name an executable.
|
|
62
72
|
*
|
|
@@ -95,6 +105,23 @@ function outsideWorkspace(text, root) {
|
|
|
95
105
|
return false;
|
|
96
106
|
return !norm(abs[1]).startsWith(r);
|
|
97
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* Whether one path resolves inside `root`, lexically.
|
|
110
|
+
*
|
|
111
|
+
* Deliberately dependency-free (no `node:path`) and deliberately **case-sensitive**:
|
|
112
|
+
* this module is also consumed by the browser half, and a wrong "yes" here relaxes a
|
|
113
|
+
* safety screen, so an unprovable case must answer `false`. Symbol links and `..`
|
|
114
|
+
* escapes are left to `outsideWorkspace`/`irreversible.ts`; callers that relax opacity
|
|
115
|
+
* also refuse delete/remote-write outright.
|
|
116
|
+
*/
|
|
117
|
+
function withinRoot(root, p) {
|
|
118
|
+
if (root === undefined || root === '')
|
|
119
|
+
return false;
|
|
120
|
+
const norm = (s) => s.replace(/[\\/]+/g, '/').replace(/\/+$/, '');
|
|
121
|
+
const r = norm(root);
|
|
122
|
+
const t = norm(p);
|
|
123
|
+
return t === r || t.startsWith(`${r}/`);
|
|
124
|
+
}
|
|
98
125
|
/**
|
|
99
126
|
* Is a script this call runs **not** visible in the workspace?
|
|
100
127
|
*
|
|
@@ -182,9 +209,18 @@ function inspect(source) {
|
|
|
182
209
|
const judged = [cmd, ...decoded, ...bodyStatements(read.map((c) => `${c.ref}\n${c.body}`))];
|
|
183
210
|
const irreversible = judged.some((t) => irreversibleReason(t) !== undefined);
|
|
184
211
|
const unlearnable = judged.some((t) => neverClearReason(t) !== undefined);
|
|
212
|
+
// Lexical containment of everything this call names: the fact a tier needs before it
|
|
213
|
+
// may relax location-opacity. Empty `files` counts as "nothing outside", while a
|
|
214
|
+
// missing root can never be proven, so it stays false.
|
|
215
|
+
const files = source.files ?? [];
|
|
216
|
+
const workspaceBound = source.workspaceRoot !== undefined && source.workspaceRoot !== ''
|
|
217
|
+
&& files.every((f) => withinRoot(source.workspaceRoot, f))
|
|
218
|
+
&& !outsideWorkspace(cmd, source.workspaceRoot);
|
|
185
219
|
if (cmd.trim() === '{}') {
|
|
186
|
-
// A tool invoked with no arguments at all: nothing to read, nothing to trust.
|
|
187
|
-
|
|
220
|
+
// A tool invoked with no arguments at all: nothing to read, nothing to trust. The
|
|
221
|
+
// *location* is what is missing here, not the consequence — the call itself has no
|
|
222
|
+
// payload to hide behind, so a tier may relax this while still refusing encoded blobs.
|
|
223
|
+
return { kind: 'unknown', resolvable: false, readOnly: false, irreversible, unlearnable, opaqueKind: 'location', workspaceBound };
|
|
188
224
|
}
|
|
189
225
|
// Read-only means every stage of the pipeline only looks: a known read verb at the
|
|
190
226
|
// head of each segment, nothing but reshaping filters after the pipes, and no
|
|
@@ -209,19 +245,30 @@ function inspect(source) {
|
|
|
209
245
|
const covered = source.scriptsCovered === true && read.length > 0;
|
|
210
246
|
const execExternal = runner && !covered && (outsideWorkspace(cmd, source.workspaceRoot) || unseenScript(cmd, source.workspaceRoot));
|
|
211
247
|
const unnamed = text !== '' && unnamedOperation(text);
|
|
212
|
-
|
|
248
|
+
// Two different defects shared the old single boolean: invisible *content* and an
|
|
249
|
+
// unpinnable *location*. Only the second is a candidate for a tier-level relaxation
|
|
250
|
+
// (`consequence` still means "nobody saw what will run"). A script whose body could
|
|
251
|
+
// not be attached is invisible content **wherever it lives** — the comment above has
|
|
252
|
+
// always claimed one unreadable file keeps the call opaque, and this is the line that
|
|
253
|
+
// makes that true for a workspace-internal script too. A missing or directory-shaped
|
|
254
|
+
// target is excluded: nothing runs, so it is not invisible code.
|
|
255
|
+
const unreadableBody = (source.scriptContents ?? []).some((c) => c.unreadable !== undefined && INVISIBLE_SCRIPT_BODY.has(c.unreadable));
|
|
256
|
+
const opaque = OPAQUE.test(cmd) || execExternal || unreadableBody;
|
|
257
|
+
const opaqueKind = OPAQUE.test(cmd) || unnamed || unreadableBody ? 'consequence'
|
|
258
|
+
: execExternal ? 'location'
|
|
259
|
+
: undefined;
|
|
213
260
|
if (irreversible)
|
|
214
|
-
return { kind: 'delete', resolvable: !opaque && !unnamed, readOnly: false, irreversible, unlearnable };
|
|
261
|
+
return { kind: 'delete', resolvable: !opaque && !unnamed, readOnly: false, irreversible, unlearnable, opaqueKind, workspaceBound };
|
|
215
262
|
if (opaque || unnamed) {
|
|
216
|
-
return { kind: execExternal ? 'exec-external' : 'unknown', resolvable: false, readOnly: false, irreversible, unlearnable };
|
|
263
|
+
return { kind: execExternal ? 'exec-external' : 'unknown', resolvable: false, readOnly: false, irreversible, unlearnable, opaqueKind, workspaceBound };
|
|
217
264
|
}
|
|
218
265
|
if (RECOVERABLE_EXTERNAL.test(cmd))
|
|
219
|
-
return { kind: 'remote-write', resolvable: true, readOnly: false, irreversible, unlearnable };
|
|
266
|
+
return { kind: 'remote-write', resolvable: true, readOnly: false, irreversible, unlearnable, workspaceBound };
|
|
220
267
|
if (/\b(?:rm|del|Remove-Item|rmdir|Erase)\b/i.test(first))
|
|
221
|
-
return { kind: 'delete', resolvable: true, readOnly: false, irreversible, unlearnable };
|
|
268
|
+
return { kind: 'delete', resolvable: true, readOnly: false, irreversible, unlearnable, workspaceBound };
|
|
222
269
|
if (readOnly)
|
|
223
|
-
return { kind: 'read', resolvable: true, readOnly: true, irreversible, unlearnable };
|
|
224
|
-
return { kind: 'write', resolvable: true, readOnly: false, irreversible, unlearnable };
|
|
270
|
+
return { kind: 'read', resolvable: true, readOnly: true, irreversible, unlearnable, workspaceBound };
|
|
271
|
+
return { kind: 'write', resolvable: true, readOnly: false, irreversible, unlearnable, workspaceBound };
|
|
225
272
|
}
|
|
226
273
|
/**
|
|
227
274
|
* Grade reversibility from an inspection, never optimistically.
|
|
@@ -264,6 +311,8 @@ export function buildAskContext(source) {
|
|
|
264
311
|
readOnly: seen.readOnly,
|
|
265
312
|
irreversible: seen.irreversible,
|
|
266
313
|
unlearnable: seen.unlearnable,
|
|
314
|
+
...(seen.opaqueKind === undefined ? {} : { opaqueKind: seen.opaqueKind }),
|
|
315
|
+
workspaceBound: seen.workspaceBound === true,
|
|
267
316
|
reversibility: grade(seen),
|
|
268
317
|
};
|
|
269
318
|
}
|
package/lib/client.js
CHANGED
|
@@ -37,6 +37,8 @@ window.__ModuleLoader__.load({
|
|
|
37
37
|
"card.passHint": "(检查通过直接放行、不问人)只跑确定性机械审查器:运行前命中不可逆 / 不可沉淀 / 读不懂的载荷(含破坏性 Git 与文件系统命令、SSH 密钥/.env 等机密访问)就拦截并把理由回喂主模型,检查后无问题的其余照常直接执行。零模型调用——相当于 approval: never 的有审查版,也是 yolo 拿掉 LLM 后的劣化形态。",
|
|
38
38
|
"card.tierScopeHint": "只有落在门禁作用域(%scope)里的预设才会走到这一步;预设不在作用域内时整个门禁停用,任何开关都不会接管它的确认。",
|
|
39
39
|
"card.yolo": "YOLO — 永不人工确认:危险才拦,其余放行",
|
|
40
|
+
"card.yoloExempt": "YOLO:工作区内「落点未知」也放行",
|
|
41
|
+
"card.yoloExemptHint": "只在 YOLO 档生效。打开后,仅「位置判不清」的调用(无参数工具、工作区外脚本未读到正文)不再按「看不见」拦截;编码载荷、读不到正文的脚本、删除与远端写仍然拦,P0/凭据/不可逆一律不变。",
|
|
40
42
|
"card.yoloHint": "命中不可逆 / 不可沉淀 / 读不懂的载荷,或模型报硬风险时拦截,并把理由以「工具审核意见」回喂主模型;其余照常执行。没有可用模型时只靠确定性规则网拦截。",
|
|
41
43
|
"card.rulesFallback": "无模型时降级成规则闸门(cc-safety-net 级)",
|
|
42
44
|
"card.rulesFallbackHint": "只在审查模型未配置、或模型未能给出裁决时生效:按确定性规则拦危险、放行其余,不再把调用挂在没人应答的确认框上。模型正常回答时行为与之前完全一致。",
|
|
@@ -239,6 +241,8 @@ window.__ModuleLoader__.load({
|
|
|
239
241
|
"card.passHint": "(Auto-allow once the check passes, no human prompt) Runs the deterministic mechanical judge only: before execution an irreversible, unlearnable or unreadable call (including destructive Git and filesystem commands and access to SSH keys / .env credentials) is blocked and the reason fed back to the main model, everything that passes runs directly. No model call — the reviewed form of approval: never, and YOLO with the model taken away.",
|
|
240
242
|
"card.tierScopeHint": "Only presets inside the gate's scope (%scope) reach this step; outside it the whole gate stands down, so no switch takes over its confirmations.",
|
|
241
243
|
"card.yolo": "YOLO — never ask a human: block the dangerous, run the rest",
|
|
244
|
+
"card.yoloExempt": "YOLO: also allow \"unknown location\" inside the workspace",
|
|
245
|
+
"card.yoloExemptHint": "YOLO only. When on, a call whose target simply cannot be pinned down (no-argument tools, a script outside the workspace whose body was not read) is no longer blocked as \"unseen\". Encoded payloads, unreadable script bodies, deletes and remote writes are still blocked; P0, credentials and irreversible acts never change.",
|
|
242
246
|
"card.yoloHint": "Blocks an irreversible / unlearnable / unreadable payload, or a hard-risk verdict from the model, and feeds the reason back to the main LLM as a 工具审核意见 message; everything else executes. With no reviewer available only the deterministic nets catch anything.",
|
|
243
247
|
"card.rulesFallback": "Degrade to a rule-only gate when there is no model (cc-safety-net class)",
|
|
244
248
|
"card.rulesFallbackHint": "Takes effect only when the risk reviewer is not configured or gave no verdict: the deterministic nets block what they can name and let the rest through, instead of parking the call on a popup nobody will answer. While a reviewer answers, behaviour is unchanged.",
|
|
@@ -441,6 +445,8 @@ window.__ModuleLoader__.load({
|
|
|
441
445
|
"card.passHint": "決定論的な機械審査器のみを実行:不可逆 / 復元不能 / 読めない処理を検知したら遮断して理由を主モデルへ返し、それ以外は実行します。モデル呼び出しゼロ・人手確認なし。approval: never の審査付き版であり、LLM を外した YOLO の劣化形態でもあります。",
|
|
442
446
|
"card.tierScopeHint": "このステップまで到達するのはゲートの適用範囲(%scope)内のプリセットだけです。範囲外ではゲート全体が停止し、どのスイッチも確認を代行しません。",
|
|
443
447
|
"card.yolo": "YOLO — 人工確認は決して求めない:危険のみ遮断、他は実行",
|
|
448
|
+
"card.yoloExempt": "YOLO:ワークスペース内の「場所不明」も許可",
|
|
449
|
+
"card.yoloExemptHint": "YOLO 専用。オンのとき、対象の「場所」が特定できないだけの呼び出し(引数なしのツール、本文を読めていない外部スクリプト)は「見えない」としては遮断しません。エンコードされたペイロード、読めないスクリプト本文、削除・リモート書込みは従来通り遮断し、P0/資格情報/不可逆は一切変わりません。",
|
|
444
450
|
"card.yoloHint": "復元不能 / 学習不能 / 読解不能なペイロード、またはモデルの重リスク判定を遮断し、理由を「工具審核意見」メッセージでメイン LLM に返します。それ以外は実行されます。レビューモデルが無い場合は決定論的ネットのみが機能します。",
|
|
445
451
|
"card.rulesFallback": "モデル不在時はルールゲートへ劣化(cc-safety-net 級)",
|
|
446
452
|
"card.rulesFallbackHint": "レビューモデルが未設定、または判定を返せなかったときだけ発効します。決定論的ルールが名指しできる危険を遮断し、残りは通します。誰も答えない確認画面で処理を止めないためです。モデルが答えている間は挙動は変わりません。",
|
|
@@ -643,6 +649,8 @@ window.__ModuleLoader__.load({
|
|
|
643
649
|
"card.passHint": "결정론적 기계 심사기만 실행:되돌릴 수 없음 / 복원 불가 / 읽히지 않는 처리를 감지하면 차단하고 이유를 주모델에 되돌려 보내며, 나머지는 실행합니다. 모델 호출 0회·사람 확인 없음. approval: never 의 심사판이며, LLM 을 뺀 YOLO 의 열화된 형태이기도 합니다.",
|
|
644
650
|
"card.tierScopeHint": "게이트 적용 범위(%scope) 안의 프리셋만 이 단계까지 옵니다. 범위 밖에서는 게이트 전체가 중지되므로 어떤 스위치도 확인을 대신하지 않습니다.",
|
|
645
651
|
"card.yolo": "YOLO — 사람 확인은 절대 요구하지 않음: 위험만 차단하고 나머지는 실행",
|
|
652
|
+
"card.yoloExempt": "YOLO: 워크스페이스 내 “위치 불명”도 허용",
|
|
653
|
+
"card.yoloExemptHint": "YOLO 전용. 켜면 대상의 “위치”만 확인할 수 없는 호출(인자 없는 도구, 본문을 읽지 못한 외부 스크립트)은 “보이지 않음”으로 차단하지 않습니다. 인코딩된 페이로드, 읽을 수 없는 스크립트 본문, 삭제·원격 쓰기는 계속 차단되며 P0/자격 증명/비가역 작업은 전혀 바뀌지 않습니다.",
|
|
646
654
|
"card.yoloHint": "복구 불가 / 학습 불가 / 해석 불가 페이로드, 또는 모델이 위험 판정을 내리면 차단하고 이유를 「工具审核意见」 메시지로 메인 LLM에 알려합니다. 나머지는 그대로 실행됩니다. 검토 모델이 없으면 결정론적 규칙망만 작동합니다.",
|
|
647
655
|
"card.rulesFallback": "모델이 없을 때 규칙 게이트로 강등 (cc-safety-net 급)",
|
|
648
656
|
"card.rulesFallbackHint": "검토 모델이 설정되지 않았거나 판정을 내리지 못했을 때만 발동합니다. 결정론적 규칙이 식별한 위험은 차단하고 나머지는 통과시켜, 아무도 응답하지 않는 확인 창에 호출을 대기시키지 않습니다. 모델이 정상 응답하는 동안에는 동작이 변하지 않습니다.",
|
|
@@ -845,6 +853,8 @@ window.__ModuleLoader__.load({
|
|
|
845
853
|
"card.passHint": "N'exécute que le juge mécanique déterministe : une opération irréversible, irrécupérable ou illisible est bloquée et justifiée en retour au modèle principal, le reste s'exécute. Aucun appel de modèle, aucune demande humaine — la version examinée de approval: never, et le YOLO privé de son modèle.",
|
|
846
854
|
"card.tierScopeHint": "Seuls les préréglages compris dans le périmètre du garde (%scope) atteignent cette étape ; en dehors, le garde s'efface complètement et aucun interrupteur ne prend ses confirmations en charge.",
|
|
847
855
|
"card.yolo": "YOLO — ne jamais demander un humain : bloquer le dangereux, exécuter le reste",
|
|
856
|
+
"card.yoloExempt": "YOLO : autoriser aussi « lieu inconnu » dans l’espace de travail",
|
|
857
|
+
"card.yoloExemptHint": "Mode YOLO uniquement. Activé, un appel dont seule la « localisation » est indéterminable (outil sans argument, script hors de l’espace de travail dont le corps n’a pas été lu) n’est plus bloqué comme « invisible ». Les charges encodées, les corps illisibles, les suppressions et les écritures distantes restent bloqués ; P0, identifiants et irréversible ne changent jamais.",
|
|
848
858
|
"card.yoloHint": "Bloque une charge irréversible / inapprenable / illisible, ou un verdict à risque dur du modèle, et renvoie la raison au LLM principal dans un message 工具审核意见 ; tout le reste s'exécute. Sans modèle disponible, seules les filets déterministes bloquent.",
|
|
849
859
|
"card.rulesFallback": "Dégrader vers une porte à règles quand il n'y a pas de modèle (classe cc-safety-net)",
|
|
850
860
|
"card.rulesFallbackHint": "Ne s'applique que lorsque le relecteur de risque n'est pas configuré ou n'a pas rendu de verdict : les filets déterministes bloquent ce qu'ils peuvent nommer et laissent passer le reste, au lieu de immobiliser l'appel sur une popup que personne ne répondra. Tant qu'un relecteur répond, le comportement est inchangé.",
|
|
@@ -1047,6 +1057,8 @@ window.__ModuleLoader__.load({
|
|
|
1047
1057
|
"card.passHint": "Lässt nur den deterministischen mechanischen Prüfer laufen: eine irreversible, nicht rücknehmbare oder unlesbare Anfrage wird blockt und dem Hauptmodell begründet zurückgemeldet, alles andere läuft. Kein Modellaufruf, keine Frage an einen Menschen — die geprüfte Form von approval: never und YOLO ohne Modell.",
|
|
1048
1058
|
"card.tierScopeHint": "Nur Presets innerhalb des Gate-Umfangs (%scope) erreichen diesen Schritt; außerhalb davon schaltet sich das Gate komplett ab, kein Schalter übernimmt dann dessen Bestätigungen.",
|
|
1049
1059
|
"card.yolo": "YOLO — niemals einen Menschen fragen: nur Gefährliches blockieren, Rest ausführen",
|
|
1060
|
+
"card.yoloExempt": "YOLO: auch „Ort unbekannt“ im Arbeitsbereich zulassen",
|
|
1061
|
+
"card.yoloExemptHint": "Nur YOLO. Aktiviert wird ein Aufruf, bei dem nur der „Ort“ unbestimmbar ist (Werkzeug ohne Argumente, Skript außerhalb des Arbeitsbereichs ohne gelesenen Rumpf), nicht mehr als „unsichtbar“ blockiert. Kodierte Nutzlasten, unlesbare Skriptrümpfe, Löschungen und Remote-Schreibvorgänge bleiben blockiert; P0, Anmeldedaten und Unwiederbringliches ändern sich nie.",
|
|
1050
1062
|
"card.yoloHint": "Blockiert eine unwiderrufliche / nicht lernbare / unlesbare Last oder ein Hartrisiko-Urteil des Modells und meldet den Grund dem Haupt-LLM als 工具审核意见-Nachricht; alles andere läuft. Ohne erreichbares Review-Modell fangen nur die deterministischen Netze.",
|
|
1051
1063
|
"card.rulesFallback": "Ohne Modell zu einem Regel-Gate degradieren (cc-safety-net-Klasse)",
|
|
1052
1064
|
"card.rulesFallbackHint": "Greift nur, wenn das Review-Modell nicht konfiguriert ist oder kein Urteil geliefert hat: die deterministischen Netze blockieren, was sie benennen können, und lassen den Rest durch, statt den Aufruf in einem Popup warten zu lassen, das niemand beantwortet. Solange ein Modell antwortet, bleibt das Verhalten unverändert.",
|
|
@@ -1249,6 +1261,8 @@ window.__ModuleLoader__.load({
|
|
|
1249
1261
|
"card.passHint": "Esegue solo il giudice meccanico deterministico: un'operazione irreversibile, irrecuperabile o illeggibile viene bloccata e motivata al modello principale, il resto esegue. Nessuna chiamata al modello, nessuna richiesta umana: la forma esaminata di approval: never, e YOLO privato del modello.",
|
|
1250
1262
|
"card.tierScopeHint": "Solo i preset dentro l'ambito del gate (%scope) arrivano a questo passo; fuori dall'ambito il gate si disattiva del tutto e nessun interruttore prende in carico le sue conferme.",
|
|
1251
1263
|
"card.yolo": "YOLO — non chiedere mai un umano: blocca il pericoloso, esegui il resto",
|
|
1264
|
+
"card.yoloExempt": "YOLO: consenti anche “posizione sconosciuta” nel workspace",
|
|
1265
|
+
"card.yoloExemptHint": "Solo YOLO. Se attivo, una chiamata di cui è indeterminabile solo la “posizione” (strumento senza argomenti, script fuori dal workspace il cui corpo non è stato letto) non viene più bloccata come “invisibile”. Payload codificati, corpi illeggibili, eliminazioni e scritture remote restano bloccati; P0, credenziali e operazioni irreversibili non cambiano mai.",
|
|
1252
1266
|
"card.yoloHint": "Blocca un carico irreversibile / non apprendibile / illeggibile, o un verdetto a rischio duro del modello, e restituisce il motivo al LLM principale come messaggio 工具审核意见; tutto il resto viene eseguito. Senza un modello disponibile, solo le reti deterministiche intercettano.",
|
|
1253
1267
|
"card.rulesFallback": "Degradare a una porta a regole quando non c’è modello (classe cc-safety-net)",
|
|
1254
1268
|
"card.rulesFallbackHint": "Agisce solo quando il revisore di rischio non è configurato o non ha dato un verdetto: le reti deterministiche bloccano ciò che sanno nominare e lasciano passare il resto, invece di parcheggiare la chiamata su un popup che nessuno risponderà. Finché un modello risponde, il comportamento resta invariato.",
|
|
@@ -1451,6 +1465,8 @@ window.__ModuleLoader__.load({
|
|
|
1451
1465
|
"card.passHint": "Работает только детерминированный механический судья: необратимое, невосстановимое или нечитаемое действие блокируется с причиной обратно основной модели, остальное выполняется. Ни вызова модели, ни вопроса человеку — проверенная форма approval: never и YOLO без модели.",
|
|
1452
1466
|
"card.tierScopeHint": "До этого шага доходят только пресеты внутри области гейта (%scope); вне области гейт отключается целиком, и ни один переключатель не берёт его подтверждения на себя.",
|
|
1453
1467
|
"card.yolo": "YOLO — никогда не спрашивать человека: блокировать опасное, остальное выполнять",
|
|
1468
|
+
"card.yoloExempt": "YOLO: разрешить и «неизвестное расположение» внутри рабочей области",
|
|
1469
|
+
"card.yoloExemptHint": "Только для YOLO. Если включено, вызов, у которого неопределимо только «расположение» (инструмент без аргументов, скрипт вне рабочей области, тело которого не прочитано), больше не блокируется как «невидимый». Кодированные полезные нагрузки, нечитаемые тела скриптов, удаления и удалённые записи по-прежнему блокируются; P0, учётные данные и необратимые действия не меняются никогда.",
|
|
1454
1470
|
"card.yoloHint": "Блокирует необратимую / необучаемую / неразбираемую нагрузку или жёсткий вердикт модели и возвращает причину основной LLM сообщением 工具审核意见; остальное выполняется. Когда доступной модели нет, срабатывают только детерминированные сети.",
|
|
1455
1471
|
"card.rulesFallback": "Деградировать в шлюз по правилам, когда модели нет (класс cc-safety-net)",
|
|
1456
1472
|
"card.rulesFallbackHint": "Действует только когда проверяющая модель не настроена или не дала вердикта: детерминированные сети блокируют то, что могут назвать, и пропускают остальное, вместо того чтобы вешать вызов на окно, которое никто не ответит. Пока модель отвечает, поведение не меняется.",
|
|
@@ -1653,6 +1669,8 @@ window.__ModuleLoader__.load({
|
|
|
1653
1669
|
"card.passHint": "Ejecuta solo el juez mecánico determinista: una operación irreversible, irrecuperable o ilegible se bloquea y se devuelve justificada al modelo principal; lo demás corre. Ninguna llamada al modelo, ninguna pregunta humana: la forma revisada de approval: never, y un YOLO sin modelo.",
|
|
1654
1670
|
"card.tierScopeHint": "Solo los presets dentro del alcance del gate (%scope) llegan a este paso; fuera de él el gate se aparta por completo y ningún interruptor toma sus confirmaciones.",
|
|
1655
1671
|
"card.yolo": "YOLO — nunca pedir un humano: bloquear lo peligroso, ejecutar el resto",
|
|
1672
|
+
"card.yoloExempt": "YOLO: permitir también “ubicación desconocida” dentro del workspace",
|
|
1673
|
+
"card.yoloExemptHint": "Solo YOLO. Activado, una llamada en la que solo la “ubicación” es indeterminable (herramienta sin argumentos, script fuera del workspace cuyo cuerpo no se leyó) ya no se bloquea por “invisible”. Las cargas codificadas, los cuerpos ilegibles, los borrados y las escrituras remotas siguen bloqueados; P0, credenciales e irreversible nunca cambian.",
|
|
1656
1674
|
"card.yoloHint": "Bloquea una carga irreversible / no aprendible / ilegible, o un veredicto de riesgo duro del modelo, y devuelve la razón al LLM principal como mensaje 工具审核意见; todo lo demás se ejecuta. Sin un modelo disponible, solo las redes deterministas interceptan.",
|
|
1657
1675
|
"card.rulesFallback": "Degradar a una compuerta de reglas cuando no hay modelo (clase cc-safety-net)",
|
|
1658
1676
|
"card.rulesFallbackHint": "Solo actúa cuando el revisor de riesgo no está configurado o no dio veredicto: las redes deterministas bloquean lo que saben nombrar y dejan pasar el resto, en lugar de dejar la llamada colgada en un emergente que nadie responderá. Mientras un modelo responde, el comportamiento no cambia.",
|
|
@@ -2883,6 +2901,23 @@ window.__ModuleLoader__.load({
|
|
|
2883
2901
|
hint: t("card.yoloHint"),
|
|
2884
2902
|
onCommit: (next) => scope.set("yolo", next)
|
|
2885
2903
|
}),
|
|
2904
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2905
|
+
style: rowStyle,
|
|
2906
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
2907
|
+
htmlFor: "plugin-config-perm-gate-yolo-exempt",
|
|
2908
|
+
style: { fontSize: "12px" },
|
|
2909
|
+
children: t("card.yoloExempt")
|
|
2910
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PillSwitch, {
|
|
2911
|
+
id: "plugin-config-perm-gate-yolo-exempt",
|
|
2912
|
+
checked: value.yoloWorkspaceExempt === true,
|
|
2913
|
+
disabled: readonly,
|
|
2914
|
+
onCommit: (next) => scope.set("yoloWorkspaceExempt", next)
|
|
2915
|
+
})]
|
|
2916
|
+
}),
|
|
2917
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2918
|
+
style: hintStyle,
|
|
2919
|
+
children: t("card.yoloExemptHint")
|
|
2920
|
+
}),
|
|
2886
2921
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TierRow, {
|
|
2887
2922
|
id: "plugin-config-perm-gate-safenet-pass",
|
|
2888
2923
|
label: t("card.mode.pass"),
|