dsh-perm-gate 2.1.0 → 2.1.2
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 +111 -0
- package/INSTALL.ja.md +57 -1
- package/INSTALL.ko.md +54 -1
- package/INSTALL.md +53 -1
- package/INSTALL.zh.md +48 -1
- package/README.ja.md +84 -10
- package/README.ko.md +81 -10
- package/README.md +118 -22
- package/README.zh.md +86 -8
- package/cordis.patch.yml +34 -3
- package/dsh.plugin.json +22 -0
- package/lib/agent-identity.d.ts +43 -0
- package/lib/agent-identity.js +95 -0
- package/lib/client.js +114 -0
- package/lib/client.js.map +1 -1
- package/lib/compiler.d.ts +39 -0
- package/lib/compiler.js +106 -0
- package/lib/config.d.ts +95 -2
- package/lib/config.js +28 -3
- package/lib/engine.js +9 -2
- package/lib/evaluate.d.ts +9 -0
- package/lib/evaluate.js +189 -0
- package/lib/events.d.ts +13 -0
- package/lib/events.js +31 -0
- package/lib/index.d.ts +1 -1
- package/lib/index.js +235 -6
- package/lib/network-lifecycle.d.ts +107 -0
- package/lib/network-lifecycle.js +180 -0
- package/lib/network.d.ts +109 -0
- package/lib/network.js +196 -0
- package/lib/proxy.d.ts +160 -0
- package/lib/proxy.js +529 -0
- package/lib/risk.js +2 -3
- package/lib/rule-chain.d.ts +39 -0
- package/lib/rule-chain.js +222 -0
- package/lib/rule-dims.d.ts +139 -0
- package/lib/rule-dims.js +194 -0
- package/lib/rule.d.ts +25 -0
- package/lib/rule.js +15 -1
- package/lib/runtime.d.ts +87 -0
- package/lib/runtime.js +229 -2
- package/lib/session-sweep.d.ts +45 -0
- package/lib/session-sweep.js +153 -0
- package/lib/shadow.d.ts +34 -0
- package/lib/shadow.js +143 -0
- package/lib/watch.d.ts +42 -0
- package/lib/watch.js +170 -0
- package/package.json +8 -2
- package/scripts/patch-permission-glyph.mjs +209 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,117 @@ 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
|
+
## [2.1.2] - 2026-09-15
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **The composer glyph patch now ships with the package.** `scripts/patch-permission-glyph.mjs`
|
|
13
|
+
is whitelisted in `files` and exposed as the **`dsh-perm-gate-patch-glyph`** bin, so re-applying
|
|
14
|
+
the host-bundle patch after a DSH upgrade no longer needs a source checkout:
|
|
15
|
+
|
|
16
|
+
```sh
|
|
17
|
+
npx dsh-perm-gate-patch-glyph # apply
|
|
18
|
+
npx dsh-perm-gate-patch-glyph --check # report only; exits 1 if the glyph is missing
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
In a checkout, `npm run patch:glyph` and `npm run patch:glyph:check` do the same.
|
|
22
|
+
|
|
23
|
+
It is deliberately **not** a `postinstall`. The script edits a **host** package, and a plugin
|
|
24
|
+
must not rewrite the harness it is installed into without being asked. (pnpm 10+ blocks
|
|
25
|
+
install scripts by default unless they are allowlisted, so a `postinstall` would also have
|
|
26
|
+
been a promise that silently never runs — worse than an explicit command.)
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- The script is now testable: its pure parts are exported (`sliceEntry`, `applyGlyphPatch`,
|
|
31
|
+
`candidateBundles`, `findBundle`) and pinned by `test/glyph-patch.spec.ts` (11 cases). The
|
|
32
|
+
bracket-balance invariant is the one that matters — the first version of the slicer scanned
|
|
33
|
+
from the wrong bracket and produced an unparseable bundle, which only the script's own
|
|
34
|
+
`node --check` guard caught.
|
|
35
|
+
- `candidateBundles` additionally probes the hoisted per-profile scope under `$DSH_HOME`, and the
|
|
36
|
+
CLI is a no-op when imported (the main block runs only when the file is the entry point).
|
|
37
|
+
|
|
38
|
+
## [2.1.1] - 2026-09-15
|
|
39
|
+
|
|
40
|
+
### Added
|
|
41
|
+
|
|
42
|
+
- **Network execution surface (opt-in, off by default).** A local HTTP/CONNECT proxy adjudicates
|
|
43
|
+
the outbound traffic of *shell subprocesses* against the same rules file, plus an interactive
|
|
44
|
+
approval path for targets no rule covers. A `deny` rule is never escalated — approval widens
|
|
45
|
+
reach for an unlisted target, but can never override a rule that says no. New config:
|
|
46
|
+
`networkEnabled` (default `false`), `networkMode`, `networkUnlisted`, `networkUnattributed`,
|
|
47
|
+
`networkBind`, `networkPort`, `networkNoProxy`, `networkInjectEnv`, `networkAskTimeoutMs`,
|
|
48
|
+
`networkGrantTtlMs`. Diagnostics at `GET /api/dsh-perm-gate/network`. Covered by
|
|
49
|
+
`test/network.spec.ts`, `test/proxy-errors.spec.ts`, `test/network-lifecycle.spec.ts` and
|
|
50
|
+
`test/network-approval.spec.ts`.
|
|
51
|
+
- **Two 自动审查 tiers.** `permissive` keeps the built-in file sandbox; `permissive-full`
|
|
52
|
+
(label 自动审查(高权限)) pairs the same approval behaviour with `danger-full-access`. A preset's
|
|
53
|
+
`sandbox` and `approval` are independent knobs, and coupling them forced a trade: the
|
|
54
|
+
`workspace-write` sandbox also denies the named pipes a child process needs to start, so
|
|
55
|
+
`git clone`, MSYS2/Cygwin `sh.exe` and ConPTY failed under the only tier the gate was active in.
|
|
56
|
+
Both tiers are in the default `gatePresets`.
|
|
57
|
+
- **Rule model expansion.** Six new match dimensions (`params` / `absent` / `agents` / `when` /
|
|
58
|
+
`argv` / `network`), a multi-file rule chain with `searchUp` and a fallback path, and shadow
|
|
59
|
+
detection for unreachable rules. New config: `searchUp`, `fallbackPath`, `badFilePolicy`,
|
|
60
|
+
`maxChainLength`.
|
|
61
|
+
- **Rule hot reload.** A chokidar watcher reloads the effective rule files, with debounce, LRU
|
|
62
|
+
eviction across workspaces, and candidate-file watching through the deepest existing ancestor so
|
|
63
|
+
a rules file created mid-session is adopted. New config: `watch` (default `true`),
|
|
64
|
+
`watchDebounceMs`.
|
|
65
|
+
|
|
66
|
+
### Fixed
|
|
67
|
+
|
|
68
|
+
- **A blocked connection could kill the host.** When the proxy answered a CONNECT with 403, the
|
|
69
|
+
client's RST produced an `ECONNRESET` with no handler attached yet, which escalated to an
|
|
70
|
+
unhandled `'error'` event and terminated the DSH process. Socket error handlers are now attached
|
|
71
|
+
at connection time, with `clientError` and handler-rejection fallbacks behind them. A policy
|
|
72
|
+
proxy must never take down its host.
|
|
73
|
+
- **Built-in tools prompted for approval.** The auto-allow roster was hand-maintained, so tools
|
|
74
|
+
added to DSH since drifted out of it and a read-only call could raise an approval prompt:
|
|
75
|
+
`advanced_search`, `platform_search`, `free_search_test`, `context_compression_retrieve`,
|
|
76
|
+
`memory_search_graph`, `memory_expand_graph_node`, `memory_import`, `memory_ruminate`,
|
|
77
|
+
`memory_ruminate_cancel`, `memory_ruminate_status`.
|
|
78
|
+
- **Proxy lifecycle races.** `close()` now awaits an in-flight bind instead of racing it, is
|
|
79
|
+
bounded, and concurrent `start()` calls share one bind. DNS lookups are time-bounded, the
|
|
80
|
+
connection-setup phase is bounded, concurrent connections are capped, and a throwing logger can
|
|
81
|
+
no longer escalate into a crash. Proxy teardown is registered before the bind is awaited, so an
|
|
82
|
+
early dispose cannot leak a bound port or a rewritten `process.env`.
|
|
83
|
+
- **`permissive-full` had no icon in the composer picker.** The picker's glyph map is closed and,
|
|
84
|
+
by its own comment, gives host-configured names none, so 自动审查(高权限)rendered text-only
|
|
85
|
+
while 自动审查 showed shield+eye. `scripts/patch-permission-glyph.mjs` adds the missing entry to
|
|
86
|
+
that **host** map: idempotent, bracket-depth slicing, and it `node --check`s its own output and
|
|
87
|
+
restores the backup on failure. It patches a host package, so it must be re-run after every DSH
|
|
88
|
+
upgrade — reinstalling the plugin does **not** restore it, because `dsh plugin … add` only writes
|
|
89
|
+
the profile's own `node_modules`. Documented in all four INSTALL guides.
|
|
90
|
+
|
|
91
|
+
### Changed
|
|
92
|
+
|
|
93
|
+
- `networkUnattributed` defaults to `allow`: traffic with no shell attribution is DSH's own client
|
|
94
|
+
(a built-in network tool, the LLM transport), and reviewing it would let the host block itself.
|
|
95
|
+
Set `deny` for the stricter behaviour.
|
|
96
|
+
- `networkUnlisted` defaults to `ask`.
|
|
97
|
+
- `DEFAULT_GATE_PRESETS` is now `['permissive', 'permissive-full']`.
|
|
98
|
+
|
|
99
|
+
### Documented
|
|
100
|
+
|
|
101
|
+
- **The network proxy is a cooperative policy layer, not an enforcement boundary.** It only sees
|
|
102
|
+
clients that read the proxy environment. Measured, not assumed: `curl` routes through it, while
|
|
103
|
+
`node` `http`/`https`/`fetch` connect directly, as do raw sockets, DNS, QUIC, literal-IP targets
|
|
104
|
+
and Java/.NET default clients. Stated in all four READMEs.
|
|
105
|
+
|
|
106
|
+
- **Session sweep — the authorization chain now follows the session lifecycle.** On plugin startup
|
|
107
|
+
and every hour, the gate reads DSH's workspace store (`$DSH_HOME/storages/workspace.json`,
|
|
108
|
+
read-only) and classifies every session it holds gate data for. Sessions DSH has archived
|
|
109
|
+
(`global.archivedSessionIds`) or no longer tracks at all have their decision events dropped from
|
|
110
|
+
`$DSH_HOME/perm-gate/events.jsonl` (atomic tmp+rename rewrite, only when something is removed)
|
|
111
|
+
and their pre-change snapshot files deleted from `$DSH_HOME/perm-gate/snapshots/`. Live sessions
|
|
112
|
+
are untouched; unattributable rows (empty session id, unparsable line/file) are never deleted;
|
|
113
|
+
every I/O failure is fail-open (the round is skipped and retried an hour later); the hourly
|
|
114
|
+
timer is `unref`'d and disposed with the plugin. New config: `sessionSweep` (default `true`),
|
|
115
|
+
`workspaceStoreFile` (default `<dshHome>/storages/workspace.json`). Note that restoring an
|
|
116
|
+
archived session does not restore its swept history. Covered by `test/session-sweep.spec.ts`
|
|
117
|
+
(13 unit cases) and `test/session-sweep-apply.spec.ts` (end-to-end wiring).
|
|
118
|
+
|
|
8
119
|
## [2.0.0] - 2026-09-11
|
|
9
120
|
|
|
10
121
|
### Fixed
|
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` バージョン **2.
|
|
15
|
+
`dsh-perm-gate` バージョン **2.1.2**。判定チェーン、ルールファイル形式、自动审查
|
|
16
16
|
ティアについては [日本語 README](./README.ja.md) を参照してください。
|
|
17
17
|
|
|
18
18
|
## 必要条件
|
|
@@ -87,6 +87,56 @@ dsh plugin --profile web update dsh-perm-gate
|
|
|
87
87
|
dsh profile reload --profile web
|
|
88
88
|
```
|
|
89
89
|
|
|
90
|
+
## **DSH** アップグレード後:入力欄アイコンのパッチを再適用
|
|
91
|
+
|
|
92
|
+
「自动审查(高权限)」が「自动审查」と同じ盾+目のアイコンを表示するのは、
|
|
93
|
+
`scripts/patch-permission-glyph.mjs` が **DSH ホストパッケージ内の閉じた Map** に
|
|
94
|
+
その項目を追加したからにすぎません。DSH はプラグイン提供ティアに**設計上アイコンを
|
|
95
|
+
与えません** —— その Map 自身のコメントが *"host-configured names outside the design
|
|
96
|
+
set get none"* と述べています。プラグインが影響できる option オブジェクトは
|
|
97
|
+
`{value, name, description}` しか運ばないため、代わりに使えるプラグイン側のシームは
|
|
98
|
+
存在しません。
|
|
99
|
+
|
|
100
|
+
このパッチは**ホスト**のファイルを書き換えるので、**DSH のアップグレードや再インストールで
|
|
101
|
+
失われます**。*本プラグイン*のアップグレードでは失われません。アイコンは元々プラグインの
|
|
102
|
+
ものではなく、プラグイン自身の寄与(`cordis.patch.yml` の `name:` / `description:`)は
|
|
103
|
+
パッケージに同梱されています。
|
|
104
|
+
|
|
105
|
+
```sh
|
|
106
|
+
npx dsh-perm-gate-patch-glyph # パッチを適用
|
|
107
|
+
npx dsh-perm-gate-patch-glyph --check # 確認のみ。グリフが失われていれば終了コード 1
|
|
108
|
+
dsh profile reload --profile web
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
スクリプトは**このパッケージに同梱**されています —— `scripts/patch-permission-glyph.mjs`
|
|
112
|
+
としても、`dsh-perm-gate-patch-glyph` bin としても —— ソースの checkout は不要です。
|
|
113
|
+
**意図的に `postinstall` には接続していません**:これはホストパッケージを書き換えるもので、
|
|
114
|
+
プラグインが許可なく自分の harness を書き換えてよい理由はありません。適用の有無にかかわらず
|
|
115
|
+
DSH の動作に影響はなく、ティア自体はそのまま機能します。
|
|
116
|
+
|
|
117
|
+
このスクリプトは冪等(2 回目は no-op)で、バックアップは 1 度だけ取り、壊れたスライスを
|
|
118
|
+
書き込もうとしません —— 結果に対して `node --check` を実行し、失敗すればバックアップを
|
|
119
|
+
復元します —— したがって DSH アップグレードのたびに無条件で再実行して安全です。
|
|
120
|
+
実行中の `node` バイナリからパッケージを逆算するため、nvm のバージョン変更や
|
|
121
|
+
インストール symlink の貼り替えでも壊れません。
|
|
122
|
+
|
|
123
|
+
**プラグインを再インストールしてもアイコンは戻りません。**
|
|
124
|
+
`dsh plugin --profile web add …` は profile ディレクトリ内の pnpm に引数を転送し、
|
|
125
|
+
profile 自身の `node_modules` しか書き換えません(`-w` = `--workspace-root` ですが、
|
|
126
|
+
この profile の workspace は `packages: ['.']` そのものなので関係ありません)。
|
|
127
|
+
アイコンは DSH インストール側にあります。標準的なインストールでは、以下の 3 つの
|
|
128
|
+
パスは 3 つのコピーではなく **1 つの物理ファイル**です:
|
|
129
|
+
|
|
130
|
+
| パス | 実体 |
|
|
131
|
+
|------|------|
|
|
132
|
+
| `dirname(node)/node_modules/@deepseek-ai/dsh` | DSH インストール先(symlink のことがある) |
|
|
133
|
+
| `<profile>/node_modules/@deepseek-ai/dsh-client-ui-conversation` | そこへの**ジャンクション** |
|
|
134
|
+
| `<dsh>/node_modules/@deepseek-ai/dsh-client-ui-conversation/lib/client.js` | パッチ対象のファイル |
|
|
135
|
+
|
|
136
|
+
見るべき症状:ティアは動作しゲートも効いたままですが、入力欄のドロップダウンの行に
|
|
137
|
+
アイコンがなく、折りたたまれたトリガーは他のティアがアイコン+文字なのに対して
|
|
138
|
+
文字だけになります。
|
|
139
|
+
|
|
90
140
|
## 分割プラグインからの移行
|
|
91
141
|
|
|
92
142
|
`dsh-perm-gate` は、これまで `dsh-permission-rules` / `dsh-auto-mode` /
|
|
@@ -144,6 +194,12 @@ DSH の bundle patch は `permission.config.presets` を key 単位でマージ
|
|
|
144
194
|
します。profile を再読込して `cordis.patch.yml` を再適用し、後から読み込まれる
|
|
145
195
|
プラグインが `presets` を上書きしていないか確認してください。
|
|
146
196
|
|
|
197
|
+
**「自动审查(高权限)」の入力欄アイコンが消えた。**
|
|
198
|
+
DSH のアップグレードまたは再インストールが、パッチを当てたホスト bundle を置き換え
|
|
199
|
+
ました。プラグインを再インストールしても戻りません。
|
|
200
|
+
`npx dsh-perm-gate-patch-glyph` を実行して再読込してください。
|
|
201
|
+
ティア自体は影響を受けません —— パッチなしでもラベルとゲートは動作します。
|
|
202
|
+
|
|
147
203
|
**ルールファイルがあるのに `--list` が `ruleCount: 0` を返す。**
|
|
148
204
|
`rulesFile` はプラグイン ディレクトリではなく Harness プロセスの CWD から解決されます。
|
|
149
205
|
絶対パスを使うか、シェルの CWD を確認してください。不正なドキュメントは読み込み時に
|
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` 버전 **2.
|
|
15
|
+
`dsh-perm-gate` 버전 **2.1.2**. 결정 체인, 규칙 파일 형식, 自动审查 티어는
|
|
16
16
|
[한국어 README](./README.ko.md)를 참고하세요.
|
|
17
17
|
|
|
18
18
|
## 요구 사항
|
|
@@ -88,6 +88,53 @@ dsh plugin --profile web update dsh-perm-gate
|
|
|
88
88
|
dsh profile reload --profile web
|
|
89
89
|
```
|
|
90
90
|
|
|
91
|
+
## **DSH** 업그레이드 후: 입력창 아이콘 패치 재적용
|
|
92
|
+
|
|
93
|
+
「自动审查(高权限)」가 「自动审查」와 같은 방패+눈 아이콘을 보여 주는 것은
|
|
94
|
+
`scripts/patch-permission-glyph.mjs`가 **DSH 호스트 패키지 안의 닫힌 Map**에 그 항목을
|
|
95
|
+
추가했기 때문일 뿐입니다. DSH는 플러그인이 제공한 티어에 **설계상 아이콘을 주지
|
|
96
|
+
않습니다** —— 그 Map 자체의 주석이 *"host-configured names outside the design set get
|
|
97
|
+
none"*이라고 말합니다. 플러그인이 영향을 줄 수 있는 option 객체는
|
|
98
|
+
`{value, name, description}`만 나르므로, 대신 쓸 수 있는 플러그인 측 이음새가 없습니다.
|
|
99
|
+
|
|
100
|
+
이 패치는 **호스트** 파일을 고치므로 **DSH 업그레이드나 재설치에서 사라집니다**.
|
|
101
|
+
*이 플러그인*을 업그레이드할 때는 사라지지 않습니다. 아이콘은 애초에 플러그인 소유가
|
|
102
|
+
아니었고, 플러그인 자신의 기여(`cordis.patch.yml`의 `name:` / `description:`)는
|
|
103
|
+
패키지에 함께 실려 나갑니다.
|
|
104
|
+
|
|
105
|
+
```sh
|
|
106
|
+
npx dsh-perm-gate-patch-glyph # 패치 적용
|
|
107
|
+
npx dsh-perm-gate-patch-glyph --check # 확인만. 글리프가 사라졌으면 종료 코드 1
|
|
108
|
+
dsh profile reload --profile web
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
스크립트는 **이 패키지에 함께 실려 나갑니다** —— `scripts/patch-permission-glyph.mjs`로도,
|
|
112
|
+
`dsh-perm-gate-patch-glyph` bin으로도 —— 소스 checkout이 필요 없습니다.
|
|
113
|
+
**의도적으로 `postinstall`에 연결하지 않았습니다**: 이 스크립트는 호스트 패키지를 고치며,
|
|
114
|
+
플러그인이 허락 없이 자신이 설치된 harness를 다시 쓸 이유는 없습니다. 적용 여부와 무관하게
|
|
115
|
+
DSH 동작에는 영향이 없고 티어 자체는 그대로 기능합니다.
|
|
116
|
+
|
|
117
|
+
이 스크립트는 멱등이며(두 번째 실행은 no-op), 백업은 한 번만 뜨고, 잘못 잘린 조각을
|
|
118
|
+
쓰지 않습니다 —— 결과에 `node --check`를 돌려 실패하면 백업을 복원합니다 —— 따라서
|
|
119
|
+
DSH 업그레이드 때마다 무조건 다시 실행해도 안전합니다. 실행 중인 `node` 바이너리에서
|
|
120
|
+
패키지를 역산하므로 nvm 버전 변경이나 설치 symlink 재지정에도 깨지지 않습니다.
|
|
121
|
+
|
|
122
|
+
**플러그인을 재설치해도 아이콘은 돌아오지 않습니다.**
|
|
123
|
+
`dsh plugin --profile web add …`는 profile 디렉터리 안의 pnpm으로 인자를 넘기고
|
|
124
|
+
profile 자신의 `node_modules`만 씁니다(`-w` = `--workspace-root`인데, 이 profile의
|
|
125
|
+
workspace는 `packages: ['.']` 그 자체이므로 달라지는 것이 없습니다). 아이콘은 DSH
|
|
126
|
+
설치 쪽에 있습니다. 표준 설치에서 아래 세 경로는 사본 세 개가 아니라
|
|
127
|
+
**하나의 물리 파일**입니다:
|
|
128
|
+
|
|
129
|
+
| 경로 | 실체 |
|
|
130
|
+
|------|------|
|
|
131
|
+
| `dirname(node)/node_modules/@deepseek-ai/dsh` | DSH 설치 위치(symlink일 수 있음) |
|
|
132
|
+
| `<profile>/node_modules/@deepseek-ai/dsh-client-ui-conversation` | 그곳을 가리키는 **정션(junction)** |
|
|
133
|
+
| `<dsh>/node_modules/@deepseek-ai/dsh-client-ui-conversation/lib/client.js` | 패치 대상 파일 |
|
|
134
|
+
|
|
135
|
+
관찰할 증상: 티어는 여전히 동작하고 게이트도 그대로지만, 입력창 드롭다운의 그 행에
|
|
136
|
+
아이콘이 없고 접힌 트리거가 다른 티어의 아이콘+텍스트와 달리 텍스트만 표시됩니다.
|
|
137
|
+
|
|
91
138
|
## 분리된 플러그인에서 이전하기
|
|
92
139
|
|
|
93
140
|
`dsh-perm-gate`는 `dsh-permission-rules`, `dsh-auto-mode`, `dsh-auto-review`,
|
|
@@ -143,6 +190,12 @@ DSH 번들 패치는 `permission.config.presets`를 key 단위로 병합하지
|
|
|
143
190
|
합니다. profile을 다시 불러와 `cordis.patch.yml`을 재적용하고, 더 늦게 로드되는
|
|
144
191
|
플러그인이 `presets`를 덮어쓰지 않는지 확인하세요.
|
|
145
192
|
|
|
193
|
+
**「自动审查(高权限)」의 입력창 아이콘이 사라졌습니다.**
|
|
194
|
+
DSH 업그레이드나 재설치가 패치해 둔 호스트 번들을 교체했습니다. 플러그인을
|
|
195
|
+
재설치해도 되돌아오지 않습니다. `npx dsh-perm-gate-patch-glyph`를 실행하고
|
|
196
|
+
다시 불러오세요. 티어 자체는 영향받지 않습니다 —— 패치가 없어도 라벨과 게이트는
|
|
197
|
+
정상 동작합니다.
|
|
198
|
+
|
|
146
199
|
**규칙 파일이 있는데 `--list`가 `ruleCount: 0`을 표시합니다.**
|
|
147
200
|
`rulesFile`은 플러그인 디렉터리가 아니라 Harness 프로세스의 CWD에서 해석됩니다.
|
|
148
201
|
절대 경로를 쓰거나 셸의 CWD를 확인하세요. 잘못된 문서는 로드 시 loud-fail하며
|
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 **2.
|
|
15
|
+
`dsh-perm-gate` version **2.1.2**. Continue with the [README](./README.md) for the
|
|
16
16
|
decision chain, the rules file format and the 自动审查 tier.
|
|
17
17
|
|
|
18
18
|
## Requirements
|
|
@@ -88,6 +88,52 @@ Then re-apply the profile so the patch file is re-read:
|
|
|
88
88
|
dsh profile reload --profile web
|
|
89
89
|
```
|
|
90
90
|
|
|
91
|
+
## After a **DSH** upgrade: re-apply the composer glyph patch
|
|
92
|
+
|
|
93
|
+
The 自动审查(高权限) tier shows the same shield+eye glyph as 自动审查 only because
|
|
94
|
+
`scripts/patch-permission-glyph.mjs` added it to a **closed map inside a DSH host
|
|
95
|
+
package**. DSH gives host-configured tiers no glyph by design — the map's own
|
|
96
|
+
comment reads *"host-configured names outside the design set get none"* — and the
|
|
97
|
+
option objects a plugin can influence carry only `{value, name, description}`, so
|
|
98
|
+
there is no plugin-side seam to use instead.
|
|
99
|
+
|
|
100
|
+
That patch edits a **host** file, so a DSH upgrade or reinstall erases it. Upgrading
|
|
101
|
+
*this plugin* does not: the plugin never owned the glyph, and its own contribution
|
|
102
|
+
(`name:` / `description:` in `cordis.patch.yml`) ships inside the package.
|
|
103
|
+
|
|
104
|
+
```sh
|
|
105
|
+
npx dsh-perm-gate-patch-glyph # apply the patch
|
|
106
|
+
npx dsh-perm-gate-patch-glyph --check # report only; exits 1 if the glyph is gone
|
|
107
|
+
dsh profile reload --profile web
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
The script **ships inside this package** — as `scripts/patch-permission-glyph.mjs` and as
|
|
111
|
+
the `dsh-perm-gate-patch-glyph` bin — so no source checkout is needed. It is deliberately
|
|
112
|
+
**not** wired to `postinstall`: it edits a host package, and a plugin must not rewrite its
|
|
113
|
+
harness uninvited. Running DSH is unaffected either way; the tier works with or without it.
|
|
114
|
+
|
|
115
|
+
It is idempotent (a second run is a no-op), backs the bundle up once, and refuses to
|
|
116
|
+
write a mis-sliced bundle — it runs `node --check` on the result and restores the
|
|
117
|
+
backup if that fails — so it is safe to run unconditionally after every DSH upgrade.
|
|
118
|
+
It locates the bundle from the running `node` binary, so an nvm version change or a
|
|
119
|
+
re-pointed install symlink does not break it.
|
|
120
|
+
|
|
121
|
+
**Reinstalling the plugin does not restore the glyph.** `dsh plugin --profile web
|
|
122
|
+
add …` forwards to pnpm inside the profile directory and writes the profile's own
|
|
123
|
+
`node_modules` only; `-w` (`--workspace-root`, and this profile's workspace is just
|
|
124
|
+
`packages: ['.']`) changes nothing about that. The glyph lives in the DSH install.
|
|
125
|
+
On a stock install these are not three copies but **one physical file**:
|
|
126
|
+
|
|
127
|
+
| Path | What it is |
|
|
128
|
+
|------|------------|
|
|
129
|
+
| `dirname(node)/node_modules/@deepseek-ai/dsh` | the DSH install (may be a symlink) |
|
|
130
|
+
| `<profile>/node_modules/@deepseek-ai/dsh-client-ui-conversation` | a **junction** into it |
|
|
131
|
+
| `<dsh>/node_modules/@deepseek-ai/dsh-client-ui-conversation/lib/client.js` | the patched file |
|
|
132
|
+
|
|
133
|
+
Symptom to look for: the tier still works and still gates correctly, but its row in
|
|
134
|
+
the composer dropdown has no icon and the collapsed trigger renders plain text
|
|
135
|
+
where the other tiers render glyph + text.
|
|
136
|
+
|
|
91
137
|
## Migrate from the split plugins
|
|
92
138
|
|
|
93
139
|
`dsh-perm-gate` merges the gate, the approval seam and the (optional) classifier
|
|
@@ -145,6 +191,12 @@ The DSH bundle patch replaces the whole `permission.config.presets` map instead
|
|
|
145
191
|
merging per key. Reload the profile so `cordis.patch.yml` is re-applied, and make
|
|
146
192
|
sure no later plugin overwrites `presets`.
|
|
147
193
|
|
|
194
|
+
**自动审查(高权限) lost its icon in the composer.**
|
|
195
|
+
A DSH upgrade or reinstall replaced the host bundle the glyph was patched into;
|
|
196
|
+
re-running the plugin install will not bring it back. Run
|
|
197
|
+
`npx dsh-perm-gate-patch-glyph` and reload. The tier itself is
|
|
198
|
+
unaffected — its label and its gating keep working without the patch.
|
|
199
|
+
|
|
148
200
|
**`--list` reports `ruleCount: 0` although my rules file exists.**
|
|
149
201
|
`rulesFile` is resolved against the process CWD of the harness, not the plugin
|
|
150
202
|
directory. Prefer an absolute path or confirm the shell CWD. A malformed document
|
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` 版本 **2.
|
|
15
|
+
`dsh-perm-gate` 版本 **2.1.2**。裁决链、规则文件格式与自动审查档位请见
|
|
16
16
|
[中文 README](./README.zh.md)。
|
|
17
17
|
|
|
18
18
|
## 前置条件
|
|
@@ -85,6 +85,48 @@ dsh plugin --profile web update dsh-perm-gate
|
|
|
85
85
|
dsh profile reload --profile web
|
|
86
86
|
```
|
|
87
87
|
|
|
88
|
+
## **DSH** 升级后:重打输入区图标补丁
|
|
89
|
+
|
|
90
|
+
「自动审查(高权限)」之所以和「自动审查」一样显示盾+眼图标,只是因为
|
|
91
|
+
`scripts/patch-permission-glyph.mjs` 把这一项加进了 **DSH 宿主包里的一张封闭 Map**。
|
|
92
|
+
DSH 对插件档位**设计上就不给图标** —— 那张表自己的注释写着 *"host-configured
|
|
93
|
+
names outside the design set get none"*;而插件能影响的 option 对象只携带
|
|
94
|
+
`{value, name, description}`,所以插件侧没有可用的接缝。
|
|
95
|
+
|
|
96
|
+
该补丁改的是**宿主**文件,因此 **DSH 升级或重装会把它抹掉**。升级*本插件*不会:
|
|
97
|
+
图标从来不属于插件,而插件自己的贡献(`cordis.patch.yml` 里的 `name:` /
|
|
98
|
+
`description:`)随包发布。
|
|
99
|
+
|
|
100
|
+
```sh
|
|
101
|
+
npx dsh-perm-gate-patch-glyph # 应用补丁
|
|
102
|
+
npx dsh-perm-gate-patch-glyph --check # 只检查;图标已丢失时退出码为 1
|
|
103
|
+
dsh profile reload --profile web
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
脚本**随本包分发** —— 既是 `scripts/patch-permission-glyph.mjs`,也是一个
|
|
107
|
+
`dsh-perm-gate-patch-glyph` bin —— 所以不需要源码 checkout。它**故意没有**挂在
|
|
108
|
+
`postinstall` 上:它改的是宿主包,插件不该未经许可改写自己所在的 harness。有没有它
|
|
109
|
+
都不影响 DSH 运行,档位本身照常工作。
|
|
110
|
+
|
|
111
|
+
脚本是幂等的(重复执行是 no-op),只备份一次,且拒绝写坏切片 —— 它会对结果跑
|
|
112
|
+
`node --check`,失败即还原备份 —— 所以每次 DSH 升级后无条件重跑都是安全的。
|
|
113
|
+
它从运行中的 `node` 二进制反推包路径,因此 nvm 换版本或安装软链重指都不会让它失效。
|
|
114
|
+
|
|
115
|
+
**重装插件并不会恢复图标。**`dsh plugin --profile web add …` 只是把参数转发给
|
|
116
|
+
profile 目录里的 pnpm,只写 profile 自己的 `node_modules`;`-w`
|
|
117
|
+
(`--workspace-root`,而本 profile 的 workspace 就是 `packages: ['.']`)对此没有
|
|
118
|
+
任何改变。图标住在 DSH 安装里。在标准安装上,下面三条路径不是三份副本,而是
|
|
119
|
+
**同一个物理文件**:
|
|
120
|
+
|
|
121
|
+
| 路径 | 实际是什么 |
|
|
122
|
+
|------|-----------|
|
|
123
|
+
| `dirname(node)/node_modules/@deepseek-ai/dsh` | DSH 安装位(可能是软链) |
|
|
124
|
+
| `<profile>/node_modules/@deepseek-ai/dsh-client-ui-conversation` | 指向它的**目录联接(junction)** |
|
|
125
|
+
| `<dsh>/node_modules/@deepseek-ai/dsh-client-ui-conversation/lib/client.js` | 被补丁的那个文件 |
|
|
126
|
+
|
|
127
|
+
要观察的现象:档位依然工作、门禁依然生效,但它在输入区下拉里那一行没有图标,
|
|
128
|
+
收起后的触发器显示纯文字,而同排其他档位是图标+文字。
|
|
129
|
+
|
|
88
130
|
## 从分裂的插件迁移
|
|
89
131
|
|
|
90
132
|
`dsh-perm-gate` 把原先散落在 `dsh-permission-rules`、`dsh-auto-mode`、
|
|
@@ -138,6 +180,11 @@ DSH 的 bundle patch 是整体替换 `permission.config.presets`,而非逐 key
|
|
|
138
180
|
请重载 profile 让 `cordis.patch.yml` 重新生效,并确认没有更晚加载的插件覆盖了
|
|
139
181
|
`presets`。
|
|
140
182
|
|
|
183
|
+
**「自动审查(高权限)」在输入区丢了图标。**
|
|
184
|
+
DSH 升级或重装替换了被打了补丁的宿主 bundle;重装插件不会把它带回来。执行
|
|
185
|
+
`npx dsh-perm-gate-patch-glyph` 后重载即可。档位本身不受影响 ——
|
|
186
|
+
没有补丁,它的标签与门禁照常工作。
|
|
187
|
+
|
|
141
188
|
**规则文件存在但 `--list` 显示 `ruleCount: 0`。**
|
|
142
189
|
`rulesFile` 按 harness 进程的 CWD 解析,而不是插件目录。建议使用绝对路径,
|
|
143
190
|
或确认 shell 的 CWD。格式错误的文档在加载时 loud fail,绝不会静默失效。
|
package/README.ja.md
CHANGED
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
> メソッドであるため、`typeof` プロブで読み取り、欠落時やエラー時には「ポリシー
|
|
46
46
|
> 不明」にフォールバックします。
|
|
47
47
|
|
|
48
|
-
バージョン **2.
|
|
48
|
+
バージョン **2.1.2** — 変更履歴は [日本語 changelog](./CHANGELOG.ja.md) を参照。
|
|
49
49
|
|
|
50
50
|
DeepSeek Harness 向けの、単一・自己完結・決定論優先・fail-closed な権限ゲートです。
|
|
51
51
|
|
|
@@ -86,7 +86,7 @@ DSH の安全まわりのエコシステムでは、この役割が `dsh-permiss
|
|
|
86
86
|
モード**。汎用の「自動承認」でもなく、包括的な権限付与でもありません。フロントが露出する
|
|
87
87
|
のは**単一スイッチ**(`permissive`)だけで、バックエンドの 4 つの戦略は**組み合わせ
|
|
88
88
|
可能**でプラグイン設定から制御されます。P0 に対しては依然 fail-closed です。
|
|
89
|
-
|
|
89
|
+
権限ピッカーと設定行はいずれも製品名「自动审查」で表示します。アイコンについては後述(組み込みティアは標準装備、プラグイン提供ティアはパッチが必要)。
|
|
90
90
|
- **サンドボックス昇格の自動回答**(`trustEscalation`)— サンドボックス昇格は shell /
|
|
91
91
|
pwsh / edit ツールの**内部**(`tools/pre-execute` 後)から発生するためゲートはそれを
|
|
92
92
|
見ておらず、ゲートが自動許可した呼び出しでも確認プロンプトが表示されます。この戦略を
|
|
@@ -117,7 +117,7 @@ dsh plugin --profile web add dsh-perm-gate
|
|
|
117
117
|
rulesFile: ./permissions.yaml # 任意。既定は $DSH_HOME/perm-gate/rules.yml
|
|
118
118
|
dshHome: $DSH_HOME # 保護対象チェックのルート固定
|
|
119
119
|
defaultAction: ask # allow | ask | deny
|
|
120
|
-
gatePresets: [permissive]
|
|
120
|
+
gatePresets: [permissive, permissive-full] # ゲートが有効なティア(既定)
|
|
121
121
|
```
|
|
122
122
|
|
|
123
123
|
### ルール ファイル
|
|
@@ -147,6 +147,56 @@ permissions:
|
|
|
147
147
|
|
|
148
148
|
完全な例: [examples/permissions.example.yaml](./examples/permissions.example.yaml)
|
|
149
149
|
|
|
150
|
+
### ネットワークポリシー(任意で有効化)
|
|
151
|
+
|
|
152
|
+
ローカル HTTP/CONNECT プロキシです。**同じルールファイル**で **shell サブプロセス**の
|
|
153
|
+
外向き通信を審査し、どのルールにも該当しない宛先には承認経路を提供します。**既定は無効** ——
|
|
154
|
+
有効にするとループバックポートを確保し、子プロセスのプロキシ環境変数を書き換えるため、
|
|
155
|
+
暗黙に有効化されることはありません。
|
|
156
|
+
|
|
157
|
+
```yaml
|
|
158
|
+
- id: dsh-perm-gate
|
|
159
|
+
config:
|
|
160
|
+
networkEnabled: false # マスタースイッチ(既定 false)
|
|
161
|
+
networkMode: whitelist # deny-all | whitelist | allow-all
|
|
162
|
+
networkUnlisted: ask # ask | deny —— 未登録の宛先の扱い
|
|
163
|
+
networkUnattributed: allow # allow | deny —— shell 帰属のない通信
|
|
164
|
+
networkInjectEnv: true # 子プロセスに HTTP(S)_PROXY / ALL_PROXY を注入
|
|
165
|
+
networkAskTimeoutMs: 120000 # 承認待ちの上限。超過時は拒否
|
|
166
|
+
networkGrantTtlMs: 1800000 # 1 回の承認が有効なセッション期間
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**段階的な動作**:許可ルールがなければ、どの宛先にも到達できません。未登録の宛先は、
|
|
170
|
+
その接続を開いた shell コマンドのセッションに対して対話的承認へエスカレートし、承認すると
|
|
171
|
+
その宛先が当該セッションで許可されます。**`deny` ルールが承認に回ることはありません** ——
|
|
172
|
+
承認は「どのルールも禁止していない宛先」の到達性を広げられますが、禁止しているルールを
|
|
173
|
+
覆すことはできません。
|
|
174
|
+
|
|
175
|
+
**境界 —— 依存する前に必ず読んでください**:このプロキシは**協調型**のポリシー層であり、
|
|
176
|
+
強制境界ではありません。プロキシ環境変数を**読む**クライアントの通信しか見えません。
|
|
177
|
+
|
|
178
|
+
| クライアント | 遮断できるか |
|
|
179
|
+
|--------------|--------------|
|
|
180
|
+
| `curl`、`wget`、`git`、Go `net/http`、Python `requests` | ✅ |
|
|
181
|
+
| **Node.js `http` / `https` / `fetch`** | ❌ **直接接続。プロキシから見えない** |
|
|
182
|
+
| Java(`-D` プロキシ指定なし)、.NET `HttpClient` | ❌ |
|
|
183
|
+
| 生ソケット、独自 TCP | ❌ |
|
|
184
|
+
| DNS、QUIC/HTTP3、非 HTTP プロトコル | ❌ |
|
|
185
|
+
| リテラル IP への接続 | ❌ |
|
|
186
|
+
|
|
187
|
+
したがって `node -e "require('http').get('http://host/')"` のようなコマンドは**遮断されません**。
|
|
188
|
+
これは「誤操作を防ぐガードレールであり、意図を宣言する場所」と考えてください。密閉された
|
|
189
|
+
サンドボックスではありません。
|
|
190
|
+
|
|
191
|
+
DSH **自身**の通信 —— 組み込みネットワークツールと LLM トランスポート —— は意図的に対象外
|
|
192
|
+
です。これらの接続には shell 帰属がなく、`networkUnattributed: allow`(既定)がそのまま
|
|
193
|
+
通します。審査するとホストが**自分自身を遮断**してしまい、取り逃すよりはるかに悪い障害に
|
|
194
|
+
なります。ホストのクライアントがプロキシ環境変数を読まないと確信できる場合のみ `deny` に
|
|
195
|
+
してください。
|
|
196
|
+
|
|
197
|
+
稼働状態の照会:`GET /api/dsh-perm-gate/network`(モード / バインド / ポート / プロキシ稼働 /
|
|
198
|
+
環境注入状態 / 遮断カウンタ / 直近の遮断)。
|
|
199
|
+
|
|
150
200
|
## 自动审查ティア(マシン値 `permissive`)
|
|
151
201
|
|
|
152
202
|
自动审查は権限ピッカーの中で 読み取り専用 / ワークスペース内変更 / 完全権限 /
|
|
@@ -154,11 +204,33 @@ permissions:
|
|
|
154
204
|
発行することもありません。人間/LLM のシーム**の前**で判定を狭めたり広めたりする
|
|
155
205
|
だけで、P0 ハード拒否は単調かつ交渉不能のままです。
|
|
156
206
|
|
|
157
|
-
|
|
207
|
+
**2 つのバリアントを同梱します。** プリセットの `sandbox` と `approval` は**独立した**ノブであり、
|
|
208
|
+
両者を結び付けると悪いトレードオフを強いられるためです。
|
|
209
|
+
|
|
210
|
+
| ピッカーの表示名 | マシン値 | sandbox | approval |
|
|
211
|
+
|------------------|----------|---------|----------|
|
|
212
|
+
| 自动审查 | `permissive` | `workspace-write` | `ask` |
|
|
213
|
+
| 自动审查(高権限) | `permissive-full` | `danger-full-access` | `ask` |
|
|
214
|
+
|
|
215
|
+
通常のティアは組み込みのファイルサンドボックスを維持します。そのサンドボックスは子プロセスの
|
|
216
|
+
起動に必要な名前付きパイプも拒否するため、`git clone`、MSYS2/Cygwin の `sh.exe`、ConPTY は
|
|
217
|
+
`Win32 error 5` / `couldn't create signal pipe` で失敗します。しかもゲートは
|
|
218
|
+
**`gatePresets` に列挙したティアでしか動作しない**ため、ゲートを使いたい場合はこの制限を受け入れる
|
|
219
|
+
必要がありました。「自动审查(高権限)」はこの結合を解きます —— **承認動作は同一のまま、ファイル
|
|
220
|
+
サンドボックスの制限だけを外します**。どちらも既定の `gatePresets` に含まれるため、どちらを選んでも
|
|
221
|
+
P0–P4 の全チェーンが動作します。ゲートはプリセットの**名前**だけを読み、sandbox モードは読みません。
|
|
222
|
+
|
|
223
|
+
ピッカーの表示名は**ホストが供給する製品名**で、言語別辞書の項目ではありません。DSH は
|
|
158
224
|
プラグイン提供ティアの `name:` を 2 つの権限サーフェス(一般設定の既定行と入力欄のピッカー)で
|
|
159
225
|
そのまま描画し、自前のローカライズ済みラベルは 3 つの組み込み値にしか与えないため、
|
|
160
|
-
`cordis.patch.yml`
|
|
161
|
-
|
|
226
|
+
`cordis.patch.yml` は全セッション共通で中国語ラベルを配布します。
|
|
227
|
+
|
|
228
|
+
**アイコンは別の話です。** 入力欄のグリフ表は閉じており、その表自身のコメントが規則を述べています:
|
|
229
|
+
*host-configured names outside the design set get none*。`permissive` は組み込み値なので
|
|
230
|
+
「自动审查」には元から盾+目のアイコンがあります。「自动审查(高权限)」が同じアイコンを得るのは、
|
|
231
|
+
`npx dsh-perm-gate-patch-glyph` がその表に 1 項目を追加したからです。このパッチは
|
|
232
|
+
**ホスト**パッケージを書き換えるため、DSH アップグレードのたびに失われます ——
|
|
233
|
+
[DSH アップグレード後:入力欄アイコンのパッチを再適用](./INSTALL.ja.md) を参照してください。
|
|
162
234
|
|
|
163
235
|
`cordis.yml` では:
|
|
164
236
|
|
|
@@ -221,8 +293,8 @@ never` パススルー — は人手に変更なく委譲されるため、将
|
|
|
221
293
|
セッションの権限ピッカーには「auto-approval」ではなく、**独立して選択できる承認
|
|
222
294
|
ティア**として「自动审查」が並びます。
|
|
223
295
|
|
|
224
|
-
ゲートが動作するのは **`gatePresets` に列挙したティアの中だけ**です(既定
|
|
225
|
-
|
|
296
|
+
ゲートが動作するのは **`gatePresets` に列挙したティアの中だけ**です(既定
|
|
297
|
+
`['permissive', 'permissive-full']`、このプラグインが追加する 2 つのティア)。それ以外のティア(Read Only / Workspace Write /
|
|
226
298
|
Full access / `custom`)では、ゲートの判定フローは**一切実行されません**——許可も、ask も、
|
|
227
299
|
拒否も、P0 ハード拒否も、拒否キーワードの遮断も、監査イベントの記録も行いません。選択された
|
|
228
300
|
ティア自身の方針が呼び出しを決めます。`danger-full-access` の定義は「承認プロンプトなしの
|
|
@@ -258,8 +330,10 @@ Full access / `custom`)では、ゲートの判定フローは**一切実行
|
|
|
258
330
|
人手に回した `ask` は回答が返るまで追跡されます。受動的な `approval/request` オブザーバが閉じた結果を記録し(`allowed-once` → **承認**、`rejected` → **拒否**、`cancelled` → **キャンセル**、`unavailable` → 拒否=承認チャネルなし)、オブザーバが関連付けできない場合(`callId` 欠落・approval サービスなし・上流リスナーの短絡)は `tools/result` が同じ ask をフォールバックとして解決します。承認時には承認後の学習進捗(`n`/しきい値)を表示し、通知バーも 3 つの終態にラベルを付けます。
|
|
259
331
|
|
|
260
332
|
さらにプリセットの**拒否キーワード黑名単**(dsh-approval-gate の `DEFAULT_DENY_KEYWORDS` を継承:`rm -rf`、`push --force`、`drop table`、`mkfs`、`git reset --hard`、`docker system prune` など)を備え、テキストがキーワードを含む呼び出し(大小文字を区別しない部分一致)は許可リスト / 許可 / LLM より先に拒否します。設定カードでリストとして編集でき(プリセット項目にはタグ付き、ワンクリック復元対応)、未設定・空ならプリセットを適用します——黑名単が静かに無効化されることはありません。
|
|
261
|
-
|
|
262
|
-
|
|
333
|
+
「自动审查」と「自动审查(高权限)」はどちらもピッカーに盾+目のアイコンを描きます —— 前者は
|
|
334
|
+
DSH の組み込み表から、後者はインストールガイドに書かれたホストパッチからです。そのパッチが
|
|
335
|
+
ない場合、2 つ目のティアはどのサーフェスでもテキストのみになります。ラベルとゲートは影響を
|
|
336
|
+
受けません。
|
|
263
337
|
|
|
264
338
|
|
|
265
339
|
## CLI(スタンドアロン dry-run)
|