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/CHANGELOG.ja.md
CHANGED
|
@@ -9,9 +9,33 @@
|
|
|
9
9
|
|
|
10
10
|
### 追加
|
|
11
11
|
|
|
12
|
+
- Permissive ティアに `trustEscalation` 戦略を追加(ティア有効時に既定オン):ゲートがすでに許可した呼び出しの
|
|
13
|
+
サンドボックス昇格承認をここで `allowed-once` と回答し、プロンプトを出さなくする。昇格は shell / pwsh / edit
|
|
14
|
+
ツールの内部 — `tools/pre-execute` の決着後 — から発生するため、ゲート自身の allow はそこに届かず、
|
|
15
|
+
LLM が `safe` と判定した呼び出しでも広げの確認を求めていた。ゲートが許可した呼び出しのみ
|
|
16
|
+
(`callId` とツール名で一致)がプロンプトをスキップし、`workspace-write` / `danger-full-access` を
|
|
17
|
+
命名する認識された昇格原因のみ適用。それ以外は変更なく人手へ委譲。自動回答はイベントフィードに記録
|
|
18
|
+
(`verdict: "escalation-auto"`、`mode: <ターゲット>`)。スイッチをオフにすると広げは人手ゲート化。
|
|
19
|
+
|
|
20
|
+
### 修正
|
|
21
|
+
|
|
22
|
+
- 設定カードがルール ファイルから編集可能なホワイトリストをシードするようになりました。
|
|
23
|
+
`installSettingsSection` はホスト設定スコープで `scope.set('allowlist', …)` を呼んでいましたが、
|
|
24
|
+
ホスト スコープは `get` / `watch` / `update` / `replace` だけ expose —
|
|
25
|
+
`set(field, value)` は *クライアント* の `mutate()` 用 convenience ラッパーで異なるオブジェクトなので、
|
|
26
|
+
呼び出しが投げて名前空間がシードされませんでした。
|
|
27
|
+
今度は `scope.update({ allowlist: … })` を使います。
|
|
28
|
+
- `approval/request` リスナーが `prepend` で登録され、パッシブ オブザーバから回答ゲートになり、
|
|
29
|
+
ブラウザ プロンプトを描画するリモート ブリッジの前に位置するようになりました。
|
|
30
|
+
そのブリッジの後ろにリスナーがあれば、すでに示されたプロンプトしか記録できませんでした。
|
|
31
|
+
|
|
32
|
+
## [0.2.1-beta.3] - 2026-09-10
|
|
33
|
+
|
|
34
|
+
### 追加
|
|
35
|
+
|
|
12
36
|
- リスク判定 `llmAssist`:設定されたカスタム LLM(OpenAI 互換エンドポイント)が各 `ask` を
|
|
13
37
|
`safe` / `risky:<カテゴリ>` で判定。ハードカテゴリ(deletion / credential / remote / system /
|
|
14
|
-
bulk
|
|
38
|
+
bulk)は自動拒否、タイムアウトは 1 回リトライ、失敗は常に fail-closed。
|
|
15
39
|
- 裁決学習(`riskLearning`、既定オフ、`riskThreshold` 1–10、既定 3):人手で承認され実際に実行された
|
|
16
40
|
neutral リスクをカウントし、指紋一致する同一操作のみ自動許可。`$DSH_HOME/perm-gate/learning.json`
|
|
17
41
|
に永続化され、ユーザーの YAML ルールには書き込みません。
|
|
@@ -78,6 +102,16 @@
|
|
|
78
102
|
|
|
79
103
|
### 修正
|
|
80
104
|
|
|
105
|
+
- **`llmAssist` の `safe` は記録されるだけで、実際には自動許可されていませんでした。**
|
|
106
|
+
`tools/pre-execute` リスナーは `ask` を即座に返してバックグラウンドで判定していましたが、ホストへ
|
|
107
|
+
渡した ask はすでに承認 answerer へ向かっており、DSH にはそれを取り消す API がありません
|
|
108
|
+
(リクエストの `signal` ができるのは `cancelled` での決着だけです)。そのためパネルは表示され続け、
|
|
109
|
+
フィードには `safe` の自動許可が出ているのに人手でのクリックが必須でした — さらにハードリスクの
|
|
110
|
+
`auto-deny` はホストにまったく届いていませんでした。リスナーは決定を返す**前に** `refineAsk` を
|
|
111
|
+
await するようになり(`makePreExecuteListener`)、`safe` は `next()` で委譲されパネルは出ず、
|
|
112
|
+
ハードカテゴリは自動拒否、`risky:neutral` / `unresolved` / 判定失敗のみが人手の ask を維持します
|
|
113
|
+
(fail-closed)。待機時間は `riskTimeoutMs`(既定 20 秒)で上限が決まり、すでにキャンセルされた
|
|
114
|
+
呼び出しは判定をスキップします。
|
|
81
115
|
- **ユーザーが選んだ権限ティアをゲートが上書きしていました。** ゲートは独立した承認ティアを
|
|
82
116
|
持ちますが *すべての* プリセットで動作し、あらゆる越境が `ask` になって DSH 承認シームへ
|
|
83
117
|
転送され、`danger-full-access`(`approval: never`)ではそのシームが **どの answerer よりも
|
package/CHANGELOG.ko.md
CHANGED
|
@@ -9,9 +9,33 @@
|
|
|
9
9
|
|
|
10
10
|
### 추가
|
|
11
11
|
|
|
12
|
+
- Permissive 티어에 `trustEscalation` 전략 추가(티어 켜짐时 기본 켬): 게이트가 이미 허용한 호출의
|
|
13
|
+
샌드박스 승격 승인을 여기서 `allowed-once`로 응답하여 프롬프트를 표시하지 않음. 승격은 shell / pwsh / edit
|
|
14
|
+
도구 내부(`tools/pre-execute` 결착 후)에서 발생하므로 게이트의 allow는 여기에 닿지 않고,
|
|
15
|
+
LLM이 `safe`로 판정한 호출조차 승격 확인을 요구했음. 게이트가 허용한 호출만
|
|
16
|
+
(`callId` 및 툴 이름 일치) 프롬프트를 건너뛰고, `workspace-write` / `danger-full-access`를
|
|
17
|
+
명시하는 알려진 승격 원인에만 적용. 나머지는 변경 없이 사람에게 위임. 자동 응답은 이벤트 피드에 기록
|
|
18
|
+
(`verdict: "escalation-auto"`, `mode: <대상>`). 스위치를 끄면 승격은 사람 게이트화.
|
|
19
|
+
|
|
20
|
+
### 수정
|
|
21
|
+
|
|
22
|
+
- 설정 카드가 규칙 파일에서 편집 가능한 허용 목록을 시딩하도록 수정.
|
|
23
|
+
`installSettingsSection`은 호스트 설정 스코프에서 `scope.set('allowlist', …)`를 호출했지만,
|
|
24
|
+
호스트 스코프는 `get` / `watch` / `update` / `replace`만 제공 —
|
|
25
|
+
`set(field, value)`는 *클라이언트*의 `mutate()`용 convenience 래퍼로 다른 객체이므로
|
|
26
|
+
호출이 예외를 throw하고 네임스페이스가 시딩되지 않았음.
|
|
27
|
+
이제 `scope.update({ allowlist: … })`를 사용.
|
|
28
|
+
- `approval/request` 리스너가 `prepend`로 등록되고 수동 옵서버에서 응답 게이트로 바뀌어,
|
|
29
|
+
브라우저 프롬프트를 렌더링하는 원격 브리ჯ 앞에 위치하게 됨.
|
|
30
|
+
그 브리ჯ 뒤에 리스너가 있으면 이미 표시된 프롬프트만 기록 가능했음.
|
|
31
|
+
|
|
32
|
+
## [0.2.1-beta.3] - 2026-09-10
|
|
33
|
+
|
|
34
|
+
### 추가
|
|
35
|
+
|
|
12
36
|
- 위험 등급 `llmAssist`: 설정된 사용자 지정 LLM(OpenAI 호환 엔드포인트)이 각 `ask`를
|
|
13
37
|
`safe` / `risky:<카테고리>`로 판정합니다. 하드 카테고리(deletion / credential / remote / system /
|
|
14
|
-
bulk)는
|
|
38
|
+
bulk)는 자동 거부되고, 시간 초과는 1회 재시도하며, 모든 실패는 fail-closed를 유지합니다.
|
|
15
39
|
- 판정 학습(`riskLearning`, 기본 꺼짐, `riskThreshold` 1–10, 기본 3): 사람이 승인하고 실제 실행된
|
|
16
40
|
neutral 위험은 카운트되어 지문이 일치하는 동일 작업만 자동 허용 — `$DSH_HOME/perm-gate/learning.json`에
|
|
17
41
|
영속화되며 사용자 YAML 규칙에는 기록되지 않습니다.
|
|
@@ -77,6 +101,15 @@
|
|
|
77
101
|
|
|
78
102
|
### 수정
|
|
79
103
|
|
|
104
|
+
- **`llmAssist`의 `safe`는 기록만 될 뿐 실제로 자동 허용되지 않았습니다.** `tools/pre-execute`
|
|
105
|
+
리스너가 `ask`를 즉시 반환하고 백그라운드에서 판정했지만, 호스트로 넘어간 ask는 이미 승인
|
|
106
|
+
answerer로 향하고 있고 DSH에는 이를 되돌릴 API가 없습니다(요청의 `signal`이 할 수 있는 일은
|
|
107
|
+
`cancelled`로 종결시키는 것뿐입니다). 그래서 패널은 계속 표시되었고, 피드에는 `safe` 자동 허용이
|
|
108
|
+
찍혔는데도 사람이 직접 클릭해야 했습니다 — 하드 위험의 `auto-deny`는 호스트에 아예 전달되지
|
|
109
|
+
않았습니다. 이제 리스너는 결정을 반환하기 **전에** `refineAsk`를 await하며
|
|
110
|
+
(`makePreExecuteListener`), `safe`는 `next()`로 위임되어 패널이 뜨지 않고, 하드 카테고리는 자동
|
|
111
|
+
거부되며, `risky:neutral` / `unresolved` / 판정 실패만 사람에게 ask로 남습니다(fail-closed).
|
|
112
|
+
대기 시간은 `riskTimeoutMs`(기본 20초)로 제한되며, 이미 취소된 호출은 판정을 건너뜁니다.
|
|
80
113
|
- **사용자가 선택한 권한 티어를 게이트가 덮어썼습니다.** 게이트는 독립 승인 티어를 가지지만
|
|
81
114
|
*모든* 프리셋에서 동작했고, 모든 경계가 `ask`가 되어 DSH 승인 시임으로 전달되었으며,
|
|
82
115
|
`danger-full-access`(`approval: never`)에서는 그 시임이 **어떤 answerer보다도 먼저**
|
package/CHANGELOG.md
CHANGED
|
@@ -5,13 +5,61 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
-
## [
|
|
8
|
+
## [0.2.1-beta.4] - 2026-09-11
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `trustEscalation` strategy in the Permissive tier (on by default while the tier is on): a
|
|
13
|
+
sandbox-escalation approval for a call this gate already allowed is answered `allowed-once`
|
|
14
|
+
here instead of prompting you. The escalation is raised by `approveEscalation` from *inside*
|
|
15
|
+
the shell / pwsh / edit tool body — after `tools/pre-execute` settled — so the gate's own
|
|
16
|
+
allow never reached it and a call the LLM graded `safe` still asked you to approve the
|
|
17
|
+
widening. Only the exact call the gate cleared (matched by `callId` and tool name) skips the
|
|
18
|
+
prompt, and only for a recognized escalation reason naming `workspace-write` /
|
|
19
|
+
`danger-full-access`; everything else delegates to the human unchanged. The auto-answer is
|
|
20
|
+
recorded on the event feed (`verdict:"escalation-auto"`, `mode:<target>`). Turn the switch
|
|
21
|
+
off to keep sandbox widening human-gated.
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- The settings card now seeds the editable whitelist from the rules file. `installSettingsSection`
|
|
26
|
+
called `scope.set('allowlist', …)` on the **host** settings scope, which exposes only
|
|
27
|
+
`get` / `watch` / `update` / `replace` — `set(field, value)` is the *client* convenience wrapper
|
|
28
|
+
over `mutate()`, a different object — so the call threw and the namespace stayed unseeded.
|
|
29
|
+
It now uses `scope.update({ allowlist: … })`.
|
|
30
|
+
- The `approval/request` listener is registered `prepend` and is now an answering gate rather than
|
|
31
|
+
a passive observer, so it sits ahead of the remote bridge that renders the browser prompt. A
|
|
32
|
+
listener behind that bridge could only ever record a prompt that had already been shown.
|
|
33
|
+
- The browser half no longer imports `@deepseek-ai/dsh-client-runtime`, which DSH removed in
|
|
34
|
+
`0.1.2-alpha.1`. `ClientContext` now comes from `@deepseek-ai/cordis` — the alias DSH 0.1.1
|
|
35
|
+
defined as `export type ClientContext = Context`, so it names the same type on both lines — and
|
|
36
|
+
the settings card declares the four scope members it uses locally (`SettingsScopeLike`), the
|
|
37
|
+
same local-face pattern the host half already uses for the host `settings` service. The client
|
|
38
|
+
contract is byte-identical on both lines; only its exporting package moved.
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
|
|
42
|
+
- DSH compatibility now ships as **two long-lived branches**, each with its own version series,
|
|
43
|
+
`engines.dsh`, and npm dist-tag: `main` / `0.2.x` / `>=0.1.2-alpha.1 <0.2.0-0` / `latest`, and
|
|
44
|
+
`legacy` / `1.x` / `>=0.1.0-rc.7 <0.1.2-alpha.1` / `legacy`. This branch is `main`. See
|
|
45
|
+
`RELEASING.md` for the branch layout and the cherry-pick flow.
|
|
46
|
+
- On this line `ctx.slots` is declared by `@deepseek-ai/dsh-client-ui-renderer/client` — from
|
|
47
|
+
`0.1.2-alpha.1` on, `@deepseek-ai/dsh-client-runtime` is gone — so the client entry imports it.
|
|
48
|
+
- Client devDependency floors raised from `^0.1.0-rc.7` to `^0.1.5-rc.2`, and
|
|
49
|
+
`@deepseek-ai/dsh-client-ui-renderer` added. The old floor meant the build could only ever
|
|
50
|
+
resolve the 0.1.0-rc.8 package set, so this line was never compiled against.
|
|
51
|
+
- `npm run verify:line` (`scripts/verify-line.mjs`) installs this branch's line packages with
|
|
52
|
+
`npm install --no-save` and runs typecheck + tests + build against them, so a build always
|
|
53
|
+
compiles against the packages the branch ships for. `npm run verify:lines` is an opt-in drift
|
|
54
|
+
check that builds on both lines and compares the bundles.
|
|
55
|
+
|
|
56
|
+
## [0.2.1-beta.3] - 2026-09-10
|
|
9
57
|
|
|
10
58
|
### Added
|
|
11
59
|
|
|
12
60
|
- Risk-graded `llmAssist`: the configured custom LLM (any OpenAI-compatible endpoint) grades each
|
|
13
61
|
`ask` as `safe` / `risky:<category>`; hard categories (deletion / credential / remote / system /
|
|
14
|
-
bulk)
|
|
62
|
+
bulk) auto-deny, timeouts retry once, and every failure stays fail-closed.
|
|
15
63
|
- Verdict learning (`riskLearning`, off by default; `riskThreshold` 1–10, default 3): neutral-risk
|
|
16
64
|
asks confirmed by a human and actually executed count toward auto-allowing the exact same
|
|
17
65
|
operation (fingerprint-matched) — persisted to `$DSH_HOME/perm-gate/learning.json`, never into
|
|
@@ -94,6 +142,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
94
142
|
|
|
95
143
|
### Fixed
|
|
96
144
|
|
|
145
|
+
- **`llmAssist` "safe" now actually auto-allows instead of only being recorded.** The
|
|
146
|
+
`tools/pre-execute` listener returned the `ask` immediately and graded the call in the
|
|
147
|
+
background, but an ask handed to the host is already on its way to the approval answerers and
|
|
148
|
+
DSH offers no API to retract it (the request's own `signal` can only settle it `cancelled`). The
|
|
149
|
+
panel therefore still appeared and the human still had to click, while the feed showed the
|
|
150
|
+
`safe` auto-allow — and a hard-risk `auto-deny` never reached the host at all. The listener now
|
|
151
|
+
awaits `refineAsk` **before** returning the decision (`makePreExecuteListener`): `safe` delegates
|
|
152
|
+
via `next()` with no panel, a hard-risk category auto-denies, and only `risky:neutral` /
|
|
153
|
+
`unresolved` / a grader failure keep the human ask (fail-closed). The wait is bounded by
|
|
154
|
+
`riskTimeoutMs` (default 20 s) and an already-cancelled call skips grading.
|
|
97
155
|
- **The shell write-pattern layer never ran for DSH's primary shell tool.** `SHELL_TOOLS` listed
|
|
98
156
|
`bash` / `pwsh` / `sh` / `cmd` / `powershell` but not **`shell`** (DSH's own tool name) or
|
|
99
157
|
`terminal`, so `git push`, `chmod`, `tee`, redirects and every other write pattern fell through
|
package/INSTALL.ja.md
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
- [日本語 changelog](./CHANGELOG.ja.md)
|
|
13
13
|
- [한국어 changelog](./CHANGELOG.ko.md)
|
|
14
14
|
|
|
15
|
-
`dsh-perm-gate` バージョン **0.1.
|
|
15
|
+
`dsh-perm-gate` バージョン **0.2.1-beta.3**。判定チェーン、ルールファイル形式、Permissive
|
|
16
16
|
ティアについては [日本語 README](./README.ja.md) を参照してください。
|
|
17
17
|
|
|
18
18
|
## 必要条件
|
|
@@ -23,6 +23,21 @@
|
|
|
23
23
|
- インストール先の profile。ブラウザ側は `web` profile 向けにのみビルドされます
|
|
24
24
|
(`package.json` の `dsh.client.platform = "web"`)。
|
|
25
25
|
|
|
26
|
+
## DSH のバージョンに合う tag を選ぶ
|
|
27
|
+
|
|
28
|
+
単一ビルドが DSH 両ラインをカバーするため、どちらの tag を選んでも動作するコードが
|
|
29
|
+
インストールされます —— tag を残しておくのは、あなたがピン留めするバージョンが
|
|
30
|
+
各ラインで意味を持つようにするためです。
|
|
31
|
+
|
|
32
|
+
| DSH のバージョン | インストール方法 |
|
|
33
|
+
|-----------------|-----------------|
|
|
34
|
+
| `0.1.2-alpha.1` 以上(`0.1.5-rc.2` を含む) | `dsh plugin --profile web add dsh-perm-gate`(tag `latest`) |
|
|
35
|
+
| `0.1.1-rc.2` まで | `dsh plugin --profile web add dsh-perm-gate@legacy` |
|
|
36
|
+
|
|
37
|
+
DSH は `engines.dsh` を強制しないため、tag が選択メカニズムであり、互換性ゲート
|
|
38
|
+
そのものではありません。単一ビルドが両ラインをカバーする理由と tag の公開方法については、
|
|
39
|
+
[RELEASING.md](./RELEASING.md) を参照してください。
|
|
40
|
+
|
|
26
41
|
## 公式 CLI でインストール
|
|
27
42
|
|
|
28
43
|
```sh
|
|
@@ -105,11 +120,11 @@ dsh-perm-gate --rules permissions.yaml --tool bash --args '{"command":"pnpm inst
|
|
|
105
120
|
"defaultAction": "ask",
|
|
106
121
|
"ruleCount": 8,
|
|
107
122
|
"permissive": false,
|
|
108
|
-
"permissiveStrategies": { "trustAutoAllow": true, "alwaysConfirm": false, "llmAssist": false }
|
|
123
|
+
"permissiveStrategies": { "trustAutoAllow": true, "alwaysConfirm": false, "llmAssist": false, "trustEscalation": true }
|
|
109
124
|
}
|
|
110
125
|
```
|
|
111
126
|
|
|
112
|
-
UI では **設定 → プラグイン → Permissive 承認ティア** に、1 つのスイッチと
|
|
127
|
+
UI では **設定 → プラグイン → Permissive 承認ティア** に、1 つのスイッチと 4 つの
|
|
113
128
|
バックエンド戦略トグルが表示されます。
|
|
114
129
|
|
|
115
130
|
## アンインストール
|
package/INSTALL.ko.md
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
- [日本語 changelog](./CHANGELOG.ja.md)
|
|
13
13
|
- [한국어 changelog](./CHANGELOG.ko.md)
|
|
14
14
|
|
|
15
|
-
`dsh-perm-gate` 버전 **0.1.
|
|
15
|
+
`dsh-perm-gate` 버전 **0.2.1-beta.3**. 결정 체인, 규칙 파일 형식, Permissive 티어는
|
|
16
16
|
[한국어 README](./README.ko.md)를 참고하세요.
|
|
17
17
|
|
|
18
18
|
## 요구 사항
|
|
@@ -23,6 +23,21 @@
|
|
|
23
23
|
- 설치할 profile. 브라우저 절반은 `web` profile용으로만 빌드됩니다
|
|
24
24
|
(`package.json`의 `dsh.client.platform = "web"`).
|
|
25
25
|
|
|
26
|
+
## DSH 버전에 맞는 tag 선택
|
|
27
|
+
|
|
28
|
+
단일 빌드는 두 DSH 라인을 모두 커버하므로, 어느 tag를 골라도 작동하는 코드가
|
|
29
|
+
설치됩니다 —— tag를 유지하는 이유는 당신이 고정하는 버전이 각 라인에서 의미 있게
|
|
30
|
+
유지되도록 하기 위함입니다.
|
|
31
|
+
|
|
32
|
+
| DSH 버전 | 설치 방법 |
|
|
33
|
+
|----------|-----------|
|
|
34
|
+
| `0.1.2-alpha.1` 이상 (`0.1.5-rc.2` 포함) | `dsh plugin --profile web add dsh-perm-gate` (tag `latest`) |
|
|
35
|
+
| `0.1.1-rc.2` 이하 | `dsh plugin --profile web add dsh-perm-gate@legacy` |
|
|
36
|
+
|
|
37
|
+
DSH는 `engines.dsh`를 강제하지 않으므로, tag는 선택 메커니즘이지 호환성 게이트가
|
|
38
|
+
아닙니다. 단일 아티팩트가 두 라인을 커버하는 이유와 tag가 게시되는 방식에 대해서는
|
|
39
|
+
[RELEASING.md](./RELEASING.md)를 참고하세요.
|
|
40
|
+
|
|
26
41
|
## 공식 CLI로 설치
|
|
27
42
|
|
|
28
43
|
```sh
|
|
@@ -104,12 +119,12 @@ dsh-perm-gate --rules permissions.yaml --tool bash --args '{"command":"pnpm inst
|
|
|
104
119
|
"defaultAction": "ask",
|
|
105
120
|
"ruleCount": 8,
|
|
106
121
|
"permissive": false,
|
|
107
|
-
"permissiveStrategies": { "trustAutoAllow": true, "alwaysConfirm": false, "llmAssist": false }
|
|
122
|
+
"permissiveStrategies": { "trustAutoAllow": true, "alwaysConfirm": false, "llmAssist": false, "trustEscalation": true }
|
|
108
123
|
}
|
|
109
124
|
```
|
|
110
125
|
|
|
111
126
|
UI의 **설정 → 플러그인 → Permissive 승인 티어**에 스위치 하나와 백엔드 전략 토글
|
|
112
|
-
|
|
127
|
+
네 개가 표시되어야 합니다.
|
|
113
128
|
|
|
114
129
|
## 제거
|
|
115
130
|
|
package/INSTALL.md
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
- [日本語 changelog](./CHANGELOG.ja.md)
|
|
13
13
|
- [한국어 changelog](./CHANGELOG.ko.md)
|
|
14
14
|
|
|
15
|
-
`dsh-perm-gate` version **0.1.
|
|
15
|
+
`dsh-perm-gate` version **0.2.1-beta.3**. Continue with the [README](./README.md) for the
|
|
16
16
|
decision chain, the rules file format and the Permissive tier.
|
|
17
17
|
|
|
18
18
|
## Requirements
|
|
@@ -23,6 +23,20 @@ decision chain, the rules file format and the Permissive tier.
|
|
|
23
23
|
- A profile to install into — the browser half only ships for the `web` profile
|
|
24
24
|
(`dsh.client.platform = "web"` in `package.json`).
|
|
25
25
|
|
|
26
|
+
## Pick the tag for your DSH version
|
|
27
|
+
|
|
28
|
+
One build serves both DSH lines, so either tag installs working code — the tag
|
|
29
|
+
exists so a version you pin stays meaningful per line.
|
|
30
|
+
|
|
31
|
+
| Your DSH | Install |
|
|
32
|
+
|----------|---------|
|
|
33
|
+
| `0.1.2-alpha.1` or newer (incl. `0.1.5-rc.2`) | `dsh plugin --profile web add dsh-perm-gate` (tag `latest`) |
|
|
34
|
+
| up to `0.1.1-rc.2` | `dsh plugin --profile web add dsh-perm-gate@legacy` |
|
|
35
|
+
|
|
36
|
+
DSH does not enforce `engines.dsh`, so the tags are the selection mechanism rather
|
|
37
|
+
than a compatibility gate. See [RELEASING.md](./RELEASING.md) for why one artifact
|
|
38
|
+
covers both lines and how the tags are published.
|
|
39
|
+
|
|
26
40
|
## Install with the official CLI
|
|
27
41
|
|
|
28
42
|
```sh
|
|
@@ -107,12 +121,12 @@ Expected `--list` output shape:
|
|
|
107
121
|
"defaultAction": "ask",
|
|
108
122
|
"ruleCount": 8,
|
|
109
123
|
"permissive": false,
|
|
110
|
-
"permissiveStrategies": { "trustAutoAllow": true, "alwaysConfirm": false, "llmAssist": false }
|
|
124
|
+
"permissiveStrategies": { "trustAutoAllow": true, "alwaysConfirm": false, "llmAssist": false, "trustEscalation": true }
|
|
111
125
|
}
|
|
112
126
|
```
|
|
113
127
|
|
|
114
128
|
In the UI, **Settings → Plugins → Permissive approval tier** should render one
|
|
115
|
-
switch plus the
|
|
129
|
+
switch plus the four backend strategy toggles.
|
|
116
130
|
|
|
117
131
|
## Uninstall
|
|
118
132
|
|
package/INSTALL.zh.md
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
- [日本語 changelog](./CHANGELOG.ja.md)
|
|
13
13
|
- [한국어 changelog](./CHANGELOG.ko.md)
|
|
14
14
|
|
|
15
|
-
`dsh-perm-gate` 版本 **0.1.
|
|
15
|
+
`dsh-perm-gate` 版本 **0.2.1-beta.3**。裁决链、规则文件格式与 Permissive 档位请见
|
|
16
16
|
[中文 README](./README.zh.md)。
|
|
17
17
|
|
|
18
18
|
## 前置条件
|
|
@@ -23,6 +23,19 @@
|
|
|
23
23
|
- 需要一个目标 profile —— 浏览器端只为 `web` profile 构建(`package.json`
|
|
24
24
|
里 `dsh.client.platform = "web"`)。
|
|
25
25
|
|
|
26
|
+
## 按你的 DSH 版本选择 tag
|
|
27
|
+
|
|
28
|
+
单一构建同时覆盖两条 DSH 线,所以任一 tag 安装的代码都能工作 —— 保留 tag
|
|
29
|
+
是为了让你锁定的版本在每条线上都有意义。
|
|
30
|
+
|
|
31
|
+
| 你的 DSH | 安装方式 |
|
|
32
|
+
|----------|----------|
|
|
33
|
+
| `0.1.2-alpha.1` 或更高(含 `0.1.5-rc.2`) | `dsh plugin --profile web add dsh-perm-gate`(tag `latest`) |
|
|
34
|
+
| 不高于 `0.1.1-rc.2` | `dsh plugin --profile web add dsh-perm-gate@legacy` |
|
|
35
|
+
|
|
36
|
+
DSH 不强制 `engines.dsh`,因此 tag 是选择机制而非兼容性关卡。
|
|
37
|
+
详见 [RELEASING.md](./RELEASING.md) 了解为何单一制品覆盖两条线以及 tag 的发布方式。
|
|
38
|
+
|
|
26
39
|
## 用官方 CLI 安装
|
|
27
40
|
|
|
28
41
|
```sh
|
|
@@ -103,11 +116,11 @@ dsh-perm-gate --rules permissions.yaml --tool bash --args '{"command":"pnpm inst
|
|
|
103
116
|
"defaultAction": "ask",
|
|
104
117
|
"ruleCount": 8,
|
|
105
118
|
"permissive": false,
|
|
106
|
-
"permissiveStrategies": { "trustAutoAllow": true, "alwaysConfirm": false, "llmAssist": false }
|
|
119
|
+
"permissiveStrategies": { "trustAutoAllow": true, "alwaysConfirm": false, "llmAssist": false, "trustEscalation": true }
|
|
107
120
|
}
|
|
108
121
|
```
|
|
109
122
|
|
|
110
|
-
UI 里 **设置 → 插件 → Permissive 审批档**
|
|
123
|
+
UI 里 **设置 → 插件 → Permissive 审批档** 应渲染出一个开关加四个后台策略开关。
|
|
111
124
|
|
|
112
125
|
## 卸载
|
|
113
126
|
|
package/README.ja.md
CHANGED
|
@@ -12,13 +12,35 @@
|
|
|
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 の
|
|
16
16
|
> `LocaleRuntime` が公開するのは `zh` / `en` のみです(`LOCALE_IDS = ["zh", "en"]`)。
|
|
17
17
|
> 素の DSH で `ja` / `ko` を選択すると `locale "<id>" is not registered` になります。
|
|
18
18
|
> `LOCALE_IDS`(locale-settings.ts)と `LOCALES` ラベル(client/index.ts)を更新した
|
|
19
19
|
> DSH fork を使って再ビルドしてください。
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
> **▼ DSH バージョン互換性**
|
|
22
|
+
>
|
|
23
|
+
> 2 つの DSH ラインが 2 つの長期ブランチから提供され、それぞれが独立したバージョン
|
|
24
|
+
> 系列、`engines.dsh`、npm dist-tag を持っています
|
|
25
|
+
> ([リリースレイアウト](./RELEASING.md)):
|
|
26
|
+
>
|
|
27
|
+
> | DSH バージョン | ブランチ | バージョン | npm タグ |
|
|
28
|
+
> | --- | --- | --- | --- |
|
|
29
|
+
> | 0.1.0-rc.7 ~ 0.1.1-rc.x | `legacy` | `1.x` | `@legacy` |
|
|
30
|
+
> | 0.1.2-alpha.1+(0.1.5-rc.2を含む) | `main` | `0.2.x` | `@latest` |
|
|
31
|
+
>
|
|
32
|
+
> `@deepseek-ai/dsh-client-runtime` は `0.1.2-alpha.1` で**削除**されました ——
|
|
33
|
+
> 単なる移動ではありません。`legacy` ラインは引き続きこれを通じて
|
|
34
|
+
> `ctx.slots` にアクセスします;`main` は
|
|
35
|
+
> `@deepseek-ai/dsh-client-ui-renderer/client` から同じ宣言を取得します。
|
|
36
|
+
> 2 つのバージョン依存シームは、バージョンチェックではなく機能プロブで処理
|
|
37
|
+
> されます:(1)設定登録は `register` を使い、両ラインとも存在します
|
|
38
|
+
> (`installSection` は追加であり、置き換えではありません);(2)
|
|
39
|
+
> `effectivePolicy` は両ラインとも user-approval サービスの**プライベート**
|
|
40
|
+
> メソッドであるため、`typeof` プロブで読み取り、欠落時やエラー時には「ポリシー
|
|
41
|
+
> 不明」にフォールバックします。
|
|
42
|
+
|
|
43
|
+
バージョン **0.2.1-beta.3** — 変更履歴は [日本語 changelog](./CHANGELOG.ja.md) を参照。
|
|
22
44
|
|
|
23
45
|
DeepSeek Harness 向けの、単一・自己完結・決定論優先・fail-closed な権限ゲートです。
|
|
24
46
|
|
|
@@ -57,8 +79,13 @@ DSH の安全まわりのエコシステムでは、この役割が `dsh-permiss
|
|
|
57
79
|
モデルに見える理由と記録される結果は常に一致します。
|
|
58
80
|
- **Permissive ティア** — read-only / full-access / whitelist とは別の**独立した承認
|
|
59
81
|
モード**。「自動承認」でもなく、包括的な権限付与でもありません。フロントが露出する
|
|
60
|
-
のは**単一スイッチ**(`permissive`)だけで、バックエンドの
|
|
82
|
+
のは**単一スイッチ**(`permissive`)だけで、バックエンドの 4 つの戦略は**組み合わせ
|
|
61
83
|
可能**でプラグイン設定から制御されます。P0 に対しては依然 fail-closed です。
|
|
84
|
+
- **サンドボックス昇格の自動回答**(`trustEscalation`)— サンドボックス昇格は shell /
|
|
85
|
+
pwsh / edit ツールの**内部**(`tools/pre-execute` 後)から発生するためゲートはそれを
|
|
86
|
+
見ておらず、ゲートが自動許可した呼び出しでも確認プロンプトが表示されます。この戦略を
|
|
87
|
+
オンにすると、ゲートが許可した呼び出しを `callId` で正確に一致させてここで直接回答
|
|
88
|
+
します。
|
|
62
89
|
|
|
63
90
|
## インストール
|
|
64
91
|
|
|
@@ -133,6 +160,7 @@ Whitelist と並ぶ**独立した承認ティア**です。「自動承認」で
|
|
|
133
160
|
permissiveStrategies: # バックエンド戦略、組み合わせ可
|
|
134
161
|
trustAutoAllow: true # スコープ内安全操作は自動許可、危険/不明は ask
|
|
135
162
|
alwaysConfirm: false # すべて ask。許可コントロールに拡張ボタン 2 つ
|
|
163
|
+
trustEscalation: true # ゲートが許可済みの呼び出し自身のサンドボックス昇格は確認不要
|
|
136
164
|
llmAssist: false # まず LLM が分類、ask/失敗時は人手へ
|
|
137
165
|
```
|
|
138
166
|
|
|
@@ -144,7 +172,30 @@ Whitelist と並ぶ**独立した承認ティア**です。「自動承認」で
|
|
|
144
172
|
永続化して再読込)。`llmAssist` は設定済みの実際の LLM
|
|
145
173
|
(受信先は設定カードで選択:**カスタム API**(`classifierEndpoint` / `classifierModel`。OpenAI 互換 API なら何でも可、Xiaomi MiMo `https://api.xiaomimimo.com/v1` 等のプリセット付き)または**ホストモデルグループ**(DSH の `llm` サービスと現在のモデルグループ、`classifierProvider` / `classifierModel` で上書き可)。**健全性テスト**ボタンで受信 LLM の疎通とレイテンシを確認可能)に
|
|
146
174
|
`ask` の自動判定を委ね、`ask`/エラー時は人手のシームへフォールバックします —
|
|
147
|
-
常に fail-closed です。`
|
|
175
|
+
常に fail-closed です。`trustEscalation`(ティア有効時に既定オン)はゲートがすでに許可した呼び出し内で
|
|
176
|
+
`sandbox_permissions` 昇格が発生した際にここで回答します。以下参照。`permissive` がオフなら、ゲートの挙動は以前と完全に同じです。
|
|
177
|
+
|
|
178
|
+
### サンドボックス昇格:なぜ `safe` 判定でもプロンプトが出たか
|
|
179
|
+
|
|
180
|
+
ツール呼び出しは**2 つの独立した承認**を引き起こし得ます。ゲートが持つのが第 1 の承認 —
|
|
181
|
+
`tools/pre-execute` ウォーターフォール上の `ask` です。第 2 はツール内部の `approveEscalation`、
|
|
182
|
+
`tools/execute` 時刻に発生し、モデルが `sandbox_permissions` + `justification` を渡したとき;
|
|
183
|
+
すでに `tools/pre-execute` は決着しているため、ゲートの allow はそこに届きません。LLM が `safe` と
|
|
184
|
+
判定しゲートが自動許可した呼び出しでも、サンドボックス広げの確認プロンプトが出たままでした。
|
|
185
|
+
|
|
186
|
+
`trustEscalation` はこの隙間を埋めます。ゲートは正面向上許可した呼び出し(ホストの `callId` で
|
|
187
|
+
キー化され、昇格リクエストがこれを繰り返す)を記憶し、昇格をここで `allowed-once` と自答します。
|
|
188
|
+
**すべてが満たされる場合のみ**適用されます:
|
|
189
|
+
|
|
190
|
+
- Permissive ティアがオンで `trustEscalation` がオン;
|
|
191
|
+
- 呼び出しにゲートが許可した `callId` があり、ツール名が一致;
|
|
192
|
+
- 理由は認識された昇格で `workspace-write` または `danger-full-access` を命名。
|
|
193
|
+
|
|
194
|
+
それ以外は — 認識されない理由、異なる呼び出し、ゲートが ask した/拒否した呼び出し、`approval:
|
|
195
|
+
never` パススルー — は人手に変更なく委譲されるため、将来の DSH 変更でも open ではなく closed
|
|
196
|
+
になります。自動回答はイベントフィードに記録されます
|
|
197
|
+
(`verdict: "escalation-auto"`、`mode: <ターゲット>`)。スイッチをオフにすると広げは
|
|
198
|
+
人手ゲート化されたまま、他の許可は自動のままとします。
|
|
148
199
|
|
|
149
200
|
### 選択可能なセッション ティア
|
|
150
201
|
|
|
@@ -174,17 +225,17 @@ Full access / `custom`)では、ゲートの判定フローは**一切実行
|
|
|
174
225
|
|
|
175
226
|
このティアは実行時にも **設定 → プラグイン → Permissive 承認ティア** から調整できます
|
|
176
227
|
(プラグインのブラウザ側が描画する `settings.plugins.tab` ページ)。1 つのスイッチが
|
|
177
|
-
`permissive` を切り替え、
|
|
228
|
+
`permissive` を切り替え、4 つのトグルがバックエンドの `permissiveStrategies` を編集
|
|
178
229
|
します。host は名前空間を live に読むため、変更は再起動なしで次のツール呼び出しから
|
|
179
230
|
適用されます。これは独立した承認クラスであり、DSH の「auto-approval」モードでは
|
|
180
231
|
**ありません**。
|
|
181
232
|
|
|
182
233
|
### リスク判定 llmAssist、裁決学習、イベントフィード
|
|
183
234
|
|
|
184
|
-
`llmAssist` 有効時、設定された LLM(OpenAI 互換エンドポイントなら任意——`classifierEndpoint` / `classifierModel` / `classifierApiKey` を自分の API に向けてください)が構造化プロトコルで `ask` を 1
|
|
235
|
+
`llmAssist` 有効時、設定された LLM(OpenAI 互換エンドポイントなら任意——`classifierEndpoint` / `classifierModel` / `classifierApiKey` を自分の API に向けてください)が構造化プロトコルで `ask` を 1 件ずつ判定します。**判定はゲートの `tools/pre-execute` ウォーターフォール内、決定がホストへ返る前に行われます**:`safe` はそのまま委譲されるため承認パネルは一切表示されず、本当に判断できない判定だけが人手に回ります。
|
|
185
236
|
|
|
186
|
-
- `safe` → 自動許可(監査ソースは `classifier
|
|
187
|
-
- `risky` + **ハードリスクカテゴリ**(`deletion`、`credential`、`remote`、`system`、`bulk`)→
|
|
237
|
+
- `safe` → 自動許可(監査ソースは `classifier`)。パネルは表示されません。
|
|
238
|
+
- `risky` + **ハードリスクカテゴリ**(`deletion`、`credential`、`remote`、`system`、`bulk`)→ **自動拒否**、パネルなし。ハードリスクは自動許可も学習もされません。
|
|
188
239
|
- `risky:neutral` → `riskLearning` 有効時(設定カード内、既定オフ)、人手で承認され実際に実行された neutral リスクは `tool|カテゴリ` ごとにカウントされ、`riskThreshold`(既定 3)到達かつ新呼び出しの操作指紋(コマンド語+対象の基底名)が確認済みサンプルに一致した場合、**同一操作のみ**自動許可されます。学習沈殿(`riskSediment`、既定オン)を有効にすると、しきい値に達したキーの確認サンプルは**決定論的な許可ルール**になります:指紋の正確一致は LLM を経由せず自動許可——llmAssist オフでも継続し、沈殿ルールは設定カードで確認・管理(終止 / サンプル削除)できます。
|
|
189
240
|
- タイムアウト(`riskTimeoutMs`、既定 20 秒、1 回リトライ)、通信失敗、プロトコル外出力は元の `ask` を維持します。
|
|
190
241
|
|
package/README.ko.md
CHANGED
|
@@ -12,13 +12,33 @@
|
|
|
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
|
|
|
21
|
-
|
|
21
|
+
> **▼ DSH 버전 호환성**
|
|
22
|
+
>
|
|
23
|
+
> 두 DSH 라인 각각이 장기 유지되는 두 브랜치를 통해 제공되며, 각자 고유한
|
|
24
|
+
> 버전 시리즈, `engines.dsh`, npm dist-tag 을 가집니다
|
|
25
|
+
> ([릴아웃](./RELEASING.md)):
|
|
26
|
+
>
|
|
27
|
+
> | DSH 버전 | 브랜치 | 버전 | npm 태그 |
|
|
28
|
+
> | --- | --- | --- | --- |
|
|
29
|
+
> | 0.1.0-rc.7 ~ 0.1.1-rc.x | `legacy` | `1.x` | `@legacy` |
|
|
30
|
+
> | 0.1.2-alpha.1+ (0.1.5-rc.2 포함) | `main` | `0.2.x` | `@latest` |
|
|
31
|
+
>
|
|
32
|
+
> `@deepseek-ai/dsh-client-runtime`은 `0.1.2-alpha.1`에서 **제거**되었습니다 —
|
|
33
|
+
> 단순히 이동한 것이 아닙니다. `legacy` 라인은 여전히 이를 통해 `ctx.slots`에
|
|
34
|
+
> 접근합니다. `main`은 `@deepseek-ai/dsh-client-ui-renderer/client`에서 같은
|
|
35
|
+
> 선언을 가져옵니다. 두 버전 민감 시ーム은 버전 체크 대신 기능 프로브로 처리합니다:
|
|
36
|
+
> (1) 설정 등록은 `register`를 사용하며, 두 라인 모두에 존재합니다
|
|
37
|
+
> (`installSection`은 대체가 아닌 추가 사항); (2) `effectivePolicy`는 두 라인
|
|
38
|
+
> 모두에서 user-approval 서비스의 **개인** 메소드이므로 `typeof` 프로브를 통해
|
|
39
|
+
> 읽으며, 누락되거나 예외 발생 시 "정책_unknown"으로 후퇴합니다.
|
|
40
|
+
|
|
41
|
+
버전 **0.2.1-beta.3** — 변경 내역은 [한국어 changelog](./CHANGELOG.ko.md)를 참고하세요.
|
|
22
42
|
|
|
23
43
|
DeepSeek Harness용 단일·자족적·결정론 우선·fail-closed 권한 게이트입니다.
|
|
24
44
|
|
|
@@ -57,8 +77,12 @@ DSH 안전 생태계에서는 이 역할이 `dsh-permission-rules` / `dsh-auto-m
|
|
|
57
77
|
모델에 보이는 이유와 기록된 결과는 항상 일치합니다.
|
|
58
78
|
- **Permissive 티어** — read-only / full-access / whitelist와 구별되는 **독립 승인
|
|
59
79
|
모드**. "자동 승인"도 아니고 포괄적 권한 부여도 아닙니다. 프론트는 **단일 스위치**
|
|
60
|
-
(`permissive`)만 노출하고, 백엔드의
|
|
80
|
+
(`permissive`)만 노출하고, 백엔드의 네 가지 전략은 **조합 가능**하며 플러그인
|
|
61
81
|
설정으로 제어됩니다. P0에 대해서는 여전히 fail-closed입니다.
|
|
82
|
+
- **샌드박스 승격 자동 응답** (`trustEscalation`) — 샌드박스 승격은 shell / pwsh /
|
|
83
|
+
edit 도구의 **내부**(`tools/pre-execute` 이후)에서 발생하므로 게이트가 이를 볼 수
|
|
84
|
+
없고, 게이트가 자동 허용한 호출에도 확인 프롬프트가 나타납니다. 이 전략을 켜면 게이트가
|
|
85
|
+
`callId`로 이미 허용한 호출을 정확히 매칭하여 여기서 직접 응답합니다.
|
|
62
86
|
|
|
63
87
|
## 설치
|
|
64
88
|
|
|
@@ -133,10 +157,11 @@ Permissive는 권한 선택기에서 Read Only / Workspace Write / Full access /
|
|
|
133
157
|
permissiveStrategies: # 백엔드 전략, 조합 가능
|
|
134
158
|
trustAutoAllow: true # 범위 내 안전 작업 자동 허용, 위험/미확인은 ask
|
|
135
159
|
alwaysConfirm: false # 매번 ask. 허용 컨트롤에 확장 버튼 2개
|
|
160
|
+
trustEscalation: true # 게이트가 허용한 호출 자체의 샌드박스 승격은 확인 불필요
|
|
136
161
|
llmAssist: false # 먼저 LLM이 분류, ask/실패 시 사람에게
|
|
137
162
|
```
|
|
138
163
|
|
|
139
|
-
`trustAutoAllow
|
|
164
|
+
`trustAutoAllow`은 중간 티어의 기준선입니다(rule-allow는 자동 통과). `alwaysConfirm`은
|
|
140
165
|
모든 경계에서 승인 패널을 띄우며, 그「허용 컨트롤」에 두 개의 확장 버튼을 추가합니다 —
|
|
141
166
|
**이 세션에서 해당 유형 반복 허용**(`approveRepeat`, 유계 세션 허용)과 **모든 발생
|
|
142
167
|
허용**(`approveAllowEverywhere`, 명령어를 `permissions.yaml`의 allow 허용 목록에
|
|
@@ -145,8 +170,33 @@ Permissive는 권한 선택기에서 Read Only / Workspace Write / Full access /
|
|
|
145
170
|
프리셋 포함) 또는 **호스트 모델 그룹**(DSH의 `llm` 서비스와 현재 모델 그룹, `classifierProvider` /
|
|
146
171
|
`classifierModel`로 재정의 가능). **상태 테스트** 버튼으로 수신 LLM의 연결과 지연 시간을 확인할 수 있음)에 `ask` 자동 판정을 맡기고,
|
|
147
172
|
`ask`/오류 시 사람의 승인 심으로 폴백합니다 — 항상 fail-closed입니다.
|
|
173
|
+
`trustEscalation`(티어 켜짐时 기본 켬)은 게이트가 이미 허용한 호출 내부에서
|
|
174
|
+
`sandbox_permissions` 승격이 발생할 때 여기서 응답합니다. 아래 참조.
|
|
148
175
|
`permissive`가 꺼져 있으면 게이트는 이전과 완전히 동일하게 동작합니다.
|
|
149
176
|
|
|
177
|
+
### 샌드박스 승격: 왜 `safe` 판정에도 프롬프트가 떴나
|
|
178
|
+
|
|
179
|
+
툴 호출은 **두 개의 독립된 승인**을 일으킬 수 있습니다. 게이트가 맡는 것이 첫 번째 —
|
|
180
|
+
`tools/pre-execute` 워터폴의 `ask`입니다. 두 번째는 툴 내부의 `approveEscalation`,
|
|
181
|
+
`tools/execute` 시점, 모델이 `sandbox_permissions` + `justification`을 건넸을 때
|
|
182
|
+
발생 — 이미 `tools/pre-execute`는 끝났으므로 게이트의 allow는 여기에 닿지 않습니다.
|
|
183
|
+
LLM이 `safe`로 판정하고 게이트가 자동 허용한 호출조차 샌드박스 확장을 승인하라는
|
|
184
|
+
프롬프트가 떴습니다.
|
|
185
|
+
|
|
186
|
+
`trustEscalation`은 이 간극을 메웁니다. 게이트가 정面向上 허용한 호출(호스트의
|
|
187
|
+
`callId`로 키화, 승격 요청이 이를 반복)을 기억하고 승격을 여기서 `allowed-once`로
|
|
188
|
+
자응답합니다. **모든 조건이 충족될 때만** 적용됩니다:
|
|
189
|
+
|
|
190
|
+
- Permissive 티어가 켜져 있고 `trustEscalation`이 켜져 있음;
|
|
191
|
+
- 호출에 게이트가 허용한 `callId`가 있고, 툴 이름이 일치;
|
|
192
|
+
- 원인이 알려진 승격이며 `workspace-write` 또는 `danger-full-access`를 명시.
|
|
193
|
+
|
|
194
|
+
그 외의 모든 경우 — 알려지지 않은 원인, 다른 호출, 게이트가 ask/deny한 호출, `approval:
|
|
195
|
+
never` 패스스루 — 는 사람에 그대로 위임되므로 향후 DSH 변경이 open이 아닌 closed로
|
|
196
|
+
실패합니다. 자동 응답은 이벤트 피드에 기록됩니다
|
|
197
|
+
(`verdict: "escalation-auto"`, `mode: <대상>`). 스위치를 끄면 샌드박스 확장은
|
|
198
|
+
사람 게이트로 유지되고 다른 허용은 자동 상태를 유지합니다.
|
|
199
|
+
|
|
150
200
|
### 선택 가능한 세션 티어
|
|
151
201
|
|
|
152
202
|
`cordis.patch.yml`은 DSH의 `permission.config.presets`에 Workspace Write와
|
|
@@ -174,16 +224,16 @@ P0 하드 거부도, 거부 키워드 차단도, 감사 이벤트 기록도 하
|
|
|
174
224
|
|
|
175
225
|
이 티어는 실행 중에도 **설정 → 플러그인 → Permissive 승인 티어**에서 조정할 수 있습니다
|
|
176
226
|
(플러그인 브라우저 절반이 렌더링하는 `settings.plugins.tab` 페이지). 스위치 하나가
|
|
177
|
-
`permissive`를 토글하고,
|
|
227
|
+
`permissive`를 토글하고, 네 개가 백엔드 `permissiveStrategies`를 편집합니다.
|
|
178
228
|
host는 네임스페이스를 live로 읽으므로 변경은 재시작 없이 다음 도구 호출부터 적용됩니다.
|
|
179
229
|
이것은 독립적인 승인 클래스이며 DSH의 "auto-approval" 모드가 **아닙니다**.
|
|
180
230
|
|
|
181
231
|
### 위험 등급 llmAssist, 판정 학습, 이벤트 피드
|
|
182
232
|
|
|
183
|
-
`llmAssist`가 켜져 있으면 설정된 LLM(OpenAI 호환 엔드포인트라면 무엇이든 — `classifierEndpoint` / `classifierModel` / `classifierApiKey`을 자신의 API로 지정)이 구조화된 프로토콜로 `ask`를 하나씩
|
|
233
|
+
`llmAssist`가 켜져 있으면 설정된 LLM(OpenAI 호환 엔드포인트라면 무엇이든 — `classifierEndpoint` / `classifierModel` / `classifierApiKey`을 자신의 API로 지정)이 구조화된 프로토콜로 `ask`를 하나씩 판정합니다. **판정은 게이트의 `tools/pre-execute` 워터폴 안에서, 결정이 호스트로 반환되기 전에 이루어집니다**: `safe`는 곧바로 위임되므로 승인 패널이 아예 표시되지 않고, 정말로 판단할 수 없는 판정만 사람에게 전달됩니다.
|
|
184
234
|
|
|
185
|
-
- `safe` → 자동 허용(감사 소스 `classifier`)
|
|
186
|
-
- `risky` + **하드 위험 카테고리**(`deletion`, `credential`, `remote`, `system`, `bulk`) →
|
|
235
|
+
- `safe` → 자동 허용(감사 소스 `classifier`), 패널 없음.
|
|
236
|
+
- `risky` + **하드 위험 카테고리**(`deletion`, `credential`, `remote`, `system`, `bulk`) → **자동 거부**, 패널 없음. 하드 위험은 자동 허용도 학습도 되지 않습니다.
|
|
187
237
|
- `risky:neutral` → `riskLearning` 활성 시(설정 카드, 기본 꺼짐), 사람이 승인하고 실제 실행된 neutral 위험은 `tool|카테고리` 키로 카운트되며, `riskThreshold`(기본 3) 도달 및 새 호출의 작업 지문(명령어 단어 + 대상 기본 이름)이 확인된 샘플과 일치하면 **동일 작업만** 자동 허용됩니다. 학습 침전(`riskSediment`, 기본 켜짐)을 사용하면 임계값에 도달한 키의 확인 샘플이 **결정론적 허용 규칙**이 됩니다: 지문이 정확히 일치하면 LLM 호출 없이 바로 허용——llmAssist가 꺼져도 유지되며, 침전 규칙은 설정 카드에서 확인·관리(종료 / 샘플 삭제)할 수 있습니다.
|
|
188
238
|
- 시간 초과(`riskTimeoutMs`, 기본 20초, 1회 재시도), 전송 실패, 프로토콜 외 출력은 원래 `ask`를 유지합니다.
|
|
189
239
|
|