dsh-perm-gate 0.2.0

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.
Files changed (53) hide show
  1. package/CHANGELOG.ja.md +62 -0
  2. package/CHANGELOG.ko.md +60 -0
  3. package/CHANGELOG.md +62 -0
  4. package/INSTALL.ja.md +152 -0
  5. package/INSTALL.ko.md +151 -0
  6. package/INSTALL.md +154 -0
  7. package/INSTALL.zh.md +147 -0
  8. package/LICENSE +21 -0
  9. package/README.ja.md +197 -0
  10. package/README.ko.md +195 -0
  11. package/README.md +209 -0
  12. package/README.zh.md +144 -0
  13. package/assets/.gitkeep +0 -0
  14. package/assets/README.md +5 -0
  15. package/cordis.patch.yml +35 -0
  16. package/examples/permissions.example.yaml +20 -0
  17. package/lib/allowlist.d.ts +19 -0
  18. package/lib/allowlist.js +97 -0
  19. package/lib/audit.d.ts +45 -0
  20. package/lib/audit.js +34 -0
  21. package/lib/classifier.d.ts +74 -0
  22. package/lib/classifier.js +129 -0
  23. package/lib/cli.d.ts +2 -0
  24. package/lib/cli.js +67 -0
  25. package/lib/client.js +859 -0
  26. package/lib/client.js.map +1 -0
  27. package/lib/compiler.d.ts +30 -0
  28. package/lib/compiler.js +126 -0
  29. package/lib/config.d.ts +69 -0
  30. package/lib/config.js +64 -0
  31. package/lib/engine.d.ts +17 -0
  32. package/lib/engine.js +85 -0
  33. package/lib/evaluate.d.ts +20 -0
  34. package/lib/evaluate.js +94 -0
  35. package/lib/events.d.ts +56 -0
  36. package/lib/events.js +129 -0
  37. package/lib/grant.d.ts +60 -0
  38. package/lib/grant.js +121 -0
  39. package/lib/index.d.ts +17 -0
  40. package/lib/index.js +140 -0
  41. package/lib/learning.d.ts +58 -0
  42. package/lib/learning.js +181 -0
  43. package/lib/path.d.ts +47 -0
  44. package/lib/path.js +94 -0
  45. package/lib/risk.d.ts +58 -0
  46. package/lib/risk.js +100 -0
  47. package/lib/rule.d.ts +64 -0
  48. package/lib/rule.js +220 -0
  49. package/lib/runtime.d.ts +146 -0
  50. package/lib/runtime.js +350 -0
  51. package/lib/shell.d.ts +38 -0
  52. package/lib/shell.js +176 -0
  53. package/package.json +120 -0
@@ -0,0 +1,62 @@
1
+ # 変更履歴
2
+
3
+ このプロジェクトの重要な変更はすべてこのファイルに記録されます。
4
+
5
+ 形式は [Keep a Changelog](https://keepachangelog.com/ja/1.1.0/) に従い、
6
+ このプロジェクトは [Semantic Versioning](https://semver.org/spec/v2.0.0.html) に準拠します。
7
+
8
+ ## [Unreleased]
9
+
10
+ ### 追加
11
+
12
+ - リスク判定 `llmAssist`:設定されたカスタム LLM(OpenAI 互換エンドポイント)が各 `ask` を
13
+ `safe` / `risky:<カテゴリ>` で判定。ハードカテゴリ(deletion / credential / remote / system /
14
+ bulk)は常に人手へ、タイムアウトは 1 回リトライ、失敗は常に fail-closed。
15
+ - 裁決学習(`riskLearning`、既定オフ、`riskThreshold` 1–10、既定 3):人手で承認され実際に実行された
16
+ neutral リスクをカウントし、指紋一致する同一操作のみ自動許可。`$DSH_HOME/perm-gate/learning.json`
17
+ に永続化され、ユーザーの YAML ルールには書き込みません。
18
+ - 決定イベントフィード:各決定を `$DSH_HOME/perm-gate/events.jsonl` に追記し、
19
+ `GET /api/dsh-perm-gate/events?sessionId=&since=` で提供。ブラウザ側は入力欄上の通知バーで表示。
20
+ - 権限ピッカーの盾アイコンが折りたたみトリガーにも表示されます。
21
+
22
+ ### 変更
23
+
24
+ - `llmAssist` はリスクカテゴリプロトコルを使用(従来の allow/deny/ask 判定のスーパーセット)。
25
+ `classifier.ts` はリスク判定器と OpenAI 互換トランスポート(`chatCompletion`)を共有します。
26
+
27
+
28
+ ### Added
29
+ - **Permissive モード(独立審批枠)** — read-only / workspace-write / full-access / whitelist と並ぶ独立モード。
30
+ 単一のフロントスイッチ(`permissive`)+ 組み合わせ可能なバックエンド戦略(`trustAutoAllow` / `alwaysConfirm` / `llmAssist`)。
31
+ P0 ハード拒否は単調のまま。
32
+ - 監査に `classifier` / `permissive` の決定ソースを追加。`llmAssist` 用の注入可能な `classify` フック
33
+ (`ask`/未指定時は fail-closed)。
34
+ - CLI に `--permissive` フラグと `--list` の permissive サマリを追加。
35
+ - **ブラウザ クライアント** — `settings.plugins.tab` ページ(「Permissive 承認ティア」)が
36
+ 設定 → プラグインに描画されます。1 つのスイッチ(`permissive`)+ 3 つのバックエンド
37
+ `permissiveStrategies` トグル。host は名前空間を live に読むため、再起動なしで次の
38
+ ツール呼び出しから反映されます。
39
+ - **実際の llmAssist LLM** — 設定可能な OpenAI 互換分類器(`classifierEndpoint` /
40
+ `classifierModel`)が `ask` の自動判定を行い、人手のシームへ fail-closed でフォールバック
41
+ します。
42
+ - **ホワイトリスト移行** — `approveAllowEverywhere` はコマンド語をルール ファイルの
43
+ `allow` に永続化して再読込し、`approveRepeat` は有界なセッション許可を発行します。
44
+ いずれも always-confirm パネルの 2 つの拡張許可ボタンを裏で支えます。
45
+ - **4 言語インストール ガイド** — `INSTALL.md` / `INSTALL.zh.md` / `INSTALL.ja.md` /
46
+ `INSTALL.ko.md`(インストール・アップグレード・分割プラグインからの移行・検証・
47
+ トラブルシューティング)。全 README に言語切替リンク、`ja` / `ko` 互換性注記
48
+ (公式 DSH の `LOCALE_IDS` は `["zh", "en"]`)、バージョン表記を追加。
49
+ - README.ja / README.ko を英語の正本と同等の内容に拡張(P0–P4 チェーン表、背景/機能、
50
+ ルール ファイル形式、Permissive ティア、CLI)。
51
+
52
+ ## [0.1.0] - 2026-08-30
53
+
54
+ ### Added
55
+ - P0–P4 判定チェーン:ハード拒否 / セッション許可 / 静的な拒否優先ルール連鎖 / 任意の分類器(既定オフ)/ `ask`。
56
+ - 純関数ルールエンジン:glob/regex コンパイル+ReDoS 上限、失敗時 loud-fail、コンテンツハッシュのコンパイルキャッシュ。
57
+ - argv 分解によるコマンドホワイト/ブラックリスト(`sh -c`/`bash -c` 再帰、パイプライン、リダイレクト、再帰/強制)。
58
+ - 正準フィンガープリントによる精密なセッション許可(TTL+maxUses、対象が異なれば再利用不可)。
59
+ - `{ignorable:true}` 判定監査と、モデル可視⟺記録の不変条件。
60
+ - スタンドアロンの dry-run CLI 評価器(`dsh-perm-gate --rules … --tool … --args …`)。
61
+ - DSH cordis 関数プラグイン契約(`cordis.patch.yml`、Schemastery `Config`、exports/types)。
62
+ - 4 言語 README(en/zh/ja/ko)と Keep-a-Changelog 枠組み(en+ja+ko)。
@@ -0,0 +1,60 @@
1
+ # 변경 로그
2
+
3
+ 이 프로젝트의 중요한 변경 사항은 모두 이 파일에 기록됩니다.
4
+
5
+ 형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)을 따르며,
6
+ 이 프로젝트는 [Semantic Versioning](https://semver.org/spec/v2.0.0.html)을 준수합니다.
7
+
8
+ ## [Unreleased]
9
+
10
+ ### 추가
11
+
12
+ - 위험 등급 `llmAssist`: 설정된 사용자 지정 LLM(OpenAI 호환 엔드포인트)이 각 `ask`를
13
+ `safe` / `risky:<카테고리>`로 판정합니다. 하드 카테고리(deletion / credential / remote / system /
14
+ bulk)는 항상 사람에게 전달되고, 시간 초과는 1회 재시도하며, 모든 실패는 fail-closed를 유지합니다.
15
+ - 판정 학습(`riskLearning`, 기본 꺼짐, `riskThreshold` 1–10, 기본 3): 사람이 승인하고 실제 실행된
16
+ neutral 위험은 카운트되어 지문이 일치하는 동일 작업만 자동 허용 — `$DSH_HOME/perm-gate/learning.json`에
17
+ 영속화되며 사용자 YAML 규칙에는 기록되지 않습니다.
18
+ - 결정 이벤트 피드: 모든 결정이 `$DSH_HOME/perm-gate/events.jsonl`에 추가되고
19
+ `GET /api/dsh-perm-gate/events?sessionId=&since=`로 제공되며, 브라우저 절반이 입력창 위 알림 바로 표시합니다.
20
+ - 권한 선택기 방패 아이콘이 축소된 트리거에도 표시됩니다.
21
+
22
+ ### 변경
23
+
24
+ - `llmAssist`는 위험 카테고리 프로토콜을 사용합니다(기존 allow/deny/ask 판정의 상위 집합).
25
+ `classifier.ts`는 위험 판정기와 OpenAI 호환 전송 계층(`chatCompletion`)을 공유합니다.
26
+
27
+
28
+ ### Added
29
+ - **Permissive 모드(독립 승인 티어)** — read-only / workspace-write / full-access / whitelist와 나란한 독립 모드.
30
+ 단일 프론트 스위치(`permissive`) + 조합 가능한 백엔드 전략(`trustAutoAllow` / `alwaysConfirm` / `llmAssist`).
31
+ P0 하드 거부는 단조 유지.
32
+ - 감사 소스에 `classifier` / `permissive` 추가. `llmAssist`용 주입 가능한 `classify` 훅(`ask`/미지정 시 fail-closed).
33
+ - CLI `--permissive` 플래그와 `--list`의 permissive 요약 추가.
34
+ - **브라우저 클라이언트** — `settings.plugins.tab` 페이지("Permissive 승인 티어")가
35
+ 설정 → 플러그인에 렌더링됩니다. 스위치 하나(`permissive`) + 백엔드
36
+ `permissiveStrategies` 토글 세 개. host는 네임스페이스를 live로 읽으므로 재시작 없이
37
+ 다음 도구 호출부터 반영됩니다.
38
+ - **실제 llmAssist LLM** — 설정 가능한 OpenAI 호환 분류기(`classifierEndpoint` /
39
+ `classifierModel`)가 `ask`를 자동 판정하고, 사람 승인 심으로 fail-closed 폴백합니다.
40
+ - **허용 목록 이전** — `approveAllowEverywhere`는 명령어를 규칙 파일의 `allow`에
41
+ 영속 기록하고 재로드하며, `approveRepeat`는 유계 세션 허용을 발행합니다. 둘 다
42
+ always-confirm 패널의 확장 허용 버튼 두 개를 뒷받침합니다.
43
+ - **4개 언어 설치 안내** — `INSTALL.md` / `INSTALL.zh.md` / `INSTALL.ja.md` /
44
+ `INSTALL.ko.md`(설치·업그레이드·분리 플러그인에서의 이전·검증·문제 해결).
45
+ 모든 README에 언어 전환 링크, `ja` / `ko` 호환성 안내(공식 DSH의 `LOCALE_IDS`는
46
+ `["zh", "en"]`), 버전 표기를 추가.
47
+ - README.ko / README.ja를 영어 정본과 동등한 수준으로 확장(P0–P4 체인 표, 배경/기능,
48
+ 규칙 파일 형식, Permissive 티어, CLI).
49
+
50
+ ## [0.1.0] - 2026-08-30
51
+
52
+ ### Added
53
+ - P0–P4 결정 체인: 하드 거부 / 세션 허용 / 정적 거부 우선 규칙 체인 / 선택적 분류기(기본 꺼짐) / `ask`.
54
+ - 순수 함수 규칙 엔진: glob/regex 컴파일 + ReDoS 상한, 오류 시 loud-fail, 콘텐츠 해시 컴파일 캐시.
55
+ - argv 분해 기반 명령 화이트/블랙리스트(`sh -c`/`bash -c` 재귀, 파이프라인, 리다이렉트, 재귀/강제).
56
+ - 정규화된 지문으로 정밀한 세션 허용(TTL + maxUses, 대상이 다르면 재사용 불가).
57
+ - `{ignorable:true}` 결정 감사와 모델 가시⟺기록 불변식.
58
+ - 독립 실행 dry-run CLI 평가기(`dsh-perm-gate --rules … --tool … --args …`).
59
+ - DSH cordis 함수 플러그인 계약(`cordis.patch.yml`, Schemastery `Config`, exports/types).
60
+ - 4개 언어 README(en/zh/ja/ko) 및 Keep-a-Changelog 프레임워크(en + ja + ko).
package/CHANGELOG.md ADDED
@@ -0,0 +1,62 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Added
11
+
12
+ - Risk-graded `llmAssist`: the configured custom LLM (any OpenAI-compatible endpoint) grades each
13
+ `ask` as `safe` / `risky:<category>`; hard categories (deletion / credential / remote / system /
14
+ bulk) always ask, timeouts retry once, and every failure stays fail-closed.
15
+ - Verdict learning (`riskLearning`, off by default; `riskThreshold` 1–10, default 3): neutral-risk
16
+ asks confirmed by a human and actually executed count toward auto-allowing the exact same
17
+ operation (fingerprint-matched) — persisted to `$DSH_HOME/perm-gate/learning.json`, never into
18
+ the user's YAML rules.
19
+ - Decision event feed: every decision appends to `$DSH_HOME/perm-gate/events.jsonl` and is served
20
+ at `GET /api/dsh-perm-gate/events?sessionId=&since=`; the browser half shows the latest decision
21
+ as a notice strip above the conversation input.
22
+ - Permission-picker icon now also decorates the collapsed picker trigger.
23
+
24
+ ### Changed
25
+
26
+ - `llmAssist` now uses the risk-category protocol (superset of the previous allow/deny/ask verdicts);
27
+ `classifier.ts` shares one OpenAI-compatible transport (`chatCompletion`) with the risk grader.
28
+
29
+
30
+ ### Added
31
+ - **Permissive tier** — an independent approval mode parallel to read-only / workspace-write /
32
+ full-access / whitelist. A single front switch (`permissive`) plus combinable backend
33
+ strategies (`trustAutoAllow` / `alwaysConfirm` / `llmAssist`); P0 hard-deny stays monotonic.
34
+ - Audit `classifier` / `permissive` decision sources; optional injectable `classify` hook for
35
+ `llmAssist` (fail-closed on `ask`/absence).
36
+ - **Browser client** — a `settings.plugins.tab` page ("Permissive approval tier") renders in
37
+ Settings → Plugins: one switch (`permissive`) + three backend `permissiveStrategies` toggles.
38
+ The host reads the namespace live, so edits apply to the next tool call without a restart.
39
+ - CLI `--permissive` flag and permissive summary in `--list`.
40
+ - **Real llmAssist LLM** — a configurable OpenAI-compatible classifier (`classifierEndpoint` /
41
+ `classifierModel`), invoked to auto-decide an `ask` and fail-closed to the human seam.
42
+ - **Whitelist migration** — `approveAllowEverywhere` persists a command word into the rules
43
+ file's `allow` whitelist and reloads; `approveRepeat` mints a bounded session grant. Both back
44
+ the always-confirm panel's two extended allow buttons.
45
+ - **Four-language install guides** — `INSTALL.md` / `INSTALL.zh.md` / `INSTALL.ja.md` /
46
+ `INSTALL.ko.md` covering install, upgrade, migration from the split plugins, verification and
47
+ troubleshooting; every README gained language-switch links, a `ja` / `ko` compatibility note
48
+ (official DSH `LOCALE_IDS` is `["zh", "en"]`) and a version reference.
49
+ - README.ja / README.ko expanded to full mirrors of the English source of truth (P0–P4 chain
50
+ table, why/features, rules-file format, Permissive tier, CLI).
51
+
52
+ ## [0.1.0] - 2026-08-30
53
+
54
+ ### Added
55
+ - P0–P4 decision chain: hard-deny, session grant, static deny-first rule chain, optional classifier (off), `ask`.
56
+ - Pure-function rule engine: glob/regex compilation with ReDoS bound, loud-fail parsing, content-hash compile cache.
57
+ - Command whitelist/blacklist via argv decomposition (`sh -c`/`bash -c` recursion, pipelines, redirects, recursive/force).
58
+ - Precise session grants keyed by canonical fingerprint (TTL + maxUses, no cross-target reuse).
59
+ - `{ignorable:true}` decision audit with model-visible⟺logged invariant.
60
+ - Standalone CLI dry-run evaluator (`dsh-perm-gate --rules … --tool … --args …`).
61
+ - DSH cordis function-plugin contract (`cordis.patch.yml`, Schemastery `Config`, exports/types).
62
+ - 4-language README (en/zh/ja/ko) and Keep-a-Changelog framework (en + ja + ko).
package/INSTALL.ja.md ADDED
@@ -0,0 +1,152 @@
1
+ # インストールガイド
2
+
3
+ - [English README](./README.md)
4
+ - [中文 README](./README.zh.md)
5
+ - [日本語 README](./README.ja.md)
6
+ - [한국어 README](./README.ko.md)
7
+ - [Installation guide](./INSTALL.md)
8
+ - [中文安装指南](./INSTALL.zh.md)
9
+ - [日本語インストールガイド](./INSTALL.ja.md)
10
+ - [한국어 설치 안내](./INSTALL.ko.md)
11
+ - [Changelog](./CHANGELOG.md)
12
+ - [日本語 changelog](./CHANGELOG.ja.md)
13
+ - [한국어 changelog](./CHANGELOG.ko.md)
14
+
15
+ `dsh-perm-gate` バージョン **0.1.0**。判定チェーン、ルールファイル形式、Permissive
16
+ ティアについては [日本語 README](./README.ja.md) を参照してください。
17
+
18
+ ## 必要条件
19
+
20
+ - [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) がインストール済みであること。
21
+ - Node.js **>= 20**(`package.json` の `engines` を参照)。
22
+ - `dsh` CLI が `PATH` に存在すること。
23
+ - インストール先の profile。ブラウザ側は `web` profile 向けにのみビルドされます
24
+ (`package.json` の `dsh.client.platform = "web"`)。
25
+
26
+ ## 公式 CLI でインストール
27
+
28
+ ```sh
29
+ dsh plugin --profile web add dsh-perm-gate
30
+ ```
31
+
32
+ 公開パッケージを取得し、`cordis.patch.yml`(Permissive セッション ティアとプラグイン
33
+ 本体の挿入)を適用して、host / client の両方を組み込みます。
34
+
35
+ ## ソースからインストール
36
+
37
+ ```sh
38
+ git clone https://github.com/drscrewdriver/dsh-perm-gate.git
39
+ cd dsh-perm-gate
40
+ npm install
41
+ npm run build # tsc -> lib/*.js + lib/*.d.ts、tsdown -> lib/client.js
42
+ dsh plugin --profile web add .
43
+ ```
44
+
45
+ `npm run build` は `prepublishOnly` でもあるため、公開時に古い `lib/` が混入しません。
46
+
47
+ ## 有効化と設定
48
+
49
+ profile の `cordis.yml` にプラグインを追加します:
50
+
51
+ ```yaml
52
+ - id: dsh-perm-gate
53
+ name: dsh-perm-gate
54
+ config:
55
+ rulesFile: ./permissions.yaml # 省略時は defaultAction にフォールバック
56
+ dshHome: $DSH_HOME # 保護対象チェックのルート固定
57
+ defaultAction: ask # allow | ask | deny
58
+ ```
59
+
60
+ まずは [examples/permissions.example.yaml](./examples/permissions.example.yaml)
61
+ から始め、profile を再読込してください。
62
+
63
+ ## アップグレード
64
+
65
+ ```sh
66
+ dsh plugin --profile web update dsh-perm-gate
67
+ ```
68
+
69
+ その後、パッチファイルを再読込させるために profile を再適用します:
70
+
71
+ ```sh
72
+ dsh profile reload --profile web
73
+ ```
74
+
75
+ ## 分割プラグインからの移行
76
+
77
+ `dsh-perm-gate` は、これまで `dsh-permission-rules` / `dsh-auto-mode` /
78
+ `dsh-auto-review` / `dsh-movein-permissions` に分散していたゲート・承認シーム・
79
+ (任意の)分類器を 1 つのパッケージに統合します。
80
+
81
+ 1. 既存のルール一覧(deny / allow / ask)を書き出し、1 つの `permissions.yaml`
82
+ に統合します。
83
+ 2. 上記 4 プラグインを `cordis.yml` から削除し、`dsh-perm-gate` のエントリだけを
84
+ 追加します。
85
+ 3. それらが提供していた preset の上書きを削除します。`cordis.patch.yml` は
86
+ `permission.config.presets` を**丸ごと置換**するため、他プラグインの古い
87
+ key 単位パッチが Permissive / Auto ティアを黙って消すことがあります。
88
+ 4. profile を再読込し、後述の `--list` で検証します。
89
+
90
+ ## 検証
91
+
92
+ ```sh
93
+ # 読み込まれたルールセットのサマリ(Harness 不要)
94
+ dsh-perm-gate --rules permissions.yaml --list
95
+
96
+ # 1 回の呼び出しを dry-run
97
+ dsh-perm-gate --rules permissions.yaml --tool bash --args '{"command":"pnpm install"}'
98
+ ```
99
+
100
+ `--list` の出力例:
101
+
102
+ ```json
103
+ {
104
+ "rulesFile": "/abs/path/permissions.yaml",
105
+ "defaultAction": "ask",
106
+ "ruleCount": 8,
107
+ "permissive": false,
108
+ "permissiveStrategies": { "trustAutoAllow": true, "alwaysConfirm": false, "llmAssist": false }
109
+ }
110
+ ```
111
+
112
+ UI では **設定 → プラグイン → Permissive 承認ティア** に、1 つのスイッチと 3 つの
113
+ バックエンド戦略トグルが表示されます。
114
+
115
+ ## アンインストール
116
+
117
+ ```sh
118
+ dsh plugin --profile web remove dsh-perm-gate
119
+ dsh profile reload --profile web
120
+ ```
121
+
122
+ プラグインを削除するとパッチの寄与も失われるため、Permissive ティアはセッションの
123
+ 権限ピッカーから再び消えます。
124
+
125
+ ## トラブルシューティング
126
+
127
+ **権限ピッカーに Permissive ティアが出ない。**
128
+ DSH の bundle patch は `permission.config.presets` を key 単位でマージせず**全体置換**
129
+ します。profile を再読込して `cordis.patch.yml` を再適用し、後から読み込まれる
130
+ プラグインが `presets` を上書きしていないか確認してください。
131
+
132
+ **ルールファイルがあるのに `--list` が `ruleCount: 0` を返す。**
133
+ `rulesFile` はプラグイン ディレクトリではなく Harness プロセスの CWD から解決されます。
134
+ 絶対パスを使うか、シェルの CWD を確認してください。不正なドキュメントは読み込み時に
135
+ loud-fail し、暗黙に無効化されることはありません。
136
+
137
+ **`llmAssist` が発火しない。**
138
+ `classifierEndpoint` / `classifierModel` / `classifierApiKey` が必要です
139
+ (**設定 → プラグイン → Permissive 承認ティア** または `cordis.yml` で設定)。
140
+ 欠落や通信エラー時は人手のシームへフォールバックします。設計上 fail-closed です。
141
+
142
+ **設定カードに「設定名前空間が利用できません」と出る。**
143
+ プラグインが現在の profile に組み込まれていません。
144
+ `dsh plugin --profile web add dsh-perm-gate` を実行して再読込してください。
145
+
146
+ **`ja` / `ko` を選ぶと `locale "<id>" is not registered` になる。**
147
+ 公式 DSH の `LocaleRuntime` は `zh` / `en` のみを公開しています。
148
+ [日本語 README](./README.ja.md) の互換性に関する注記を参照してください。
149
+
150
+ ## ライセンス
151
+
152
+ [MIT](./LICENSE)
package/INSTALL.ko.md ADDED
@@ -0,0 +1,151 @@
1
+ # 설치 안내
2
+
3
+ - [English README](./README.md)
4
+ - [中文 README](./README.zh.md)
5
+ - [日本語 README](./README.ja.md)
6
+ - [한국어 README](./README.ko.md)
7
+ - [Installation guide](./INSTALL.md)
8
+ - [中文安装指南](./INSTALL.zh.md)
9
+ - [日本語インストールガイド](./INSTALL.ja.md)
10
+ - [한국어 설치 안내](./INSTALL.ko.md)
11
+ - [Changelog](./CHANGELOG.md)
12
+ - [日本語 changelog](./CHANGELOG.ja.md)
13
+ - [한국어 changelog](./CHANGELOG.ko.md)
14
+
15
+ `dsh-perm-gate` 버전 **0.1.0**. 결정 체인, 규칙 파일 형식, Permissive 티어는
16
+ [한국어 README](./README.ko.md)를 참고하세요.
17
+
18
+ ## 요구 사항
19
+
20
+ - [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)가 설치되어 있어야 합니다.
21
+ - Node.js **>= 20** (`package.json`의 `engines` 참고).
22
+ - `dsh` CLI가 `PATH`에 있어야 합니다.
23
+ - 설치할 profile. 브라우저 절반은 `web` profile용으로만 빌드됩니다
24
+ (`package.json`의 `dsh.client.platform = "web"`).
25
+
26
+ ## 공식 CLI로 설치
27
+
28
+ ```sh
29
+ dsh plugin --profile web add dsh-perm-gate
30
+ ```
31
+
32
+ 게시된 패키지를 가져오고 `cordis.patch.yml`(Permissive 세션 티어 + 플러그인 항목)을
33
+ 적용하여 host / client 양쪽을 조립합니다.
34
+
35
+ ## 소스에서 설치
36
+
37
+ ```sh
38
+ git clone https://github.com/drscrewdriver/dsh-perm-gate.git
39
+ cd dsh-perm-gate
40
+ npm install
41
+ npm run build # tsc -> lib/*.js + lib/*.d.ts, tsdown -> lib/client.js
42
+ dsh plugin --profile web add .
43
+ ```
44
+
45
+ `npm run build`는 `prepublishOnly` 단계이기도 하므로, 게시 시 오래된 `lib/`가
46
+ 포함되지 않습니다.
47
+
48
+ ## 활성화 및 설정
49
+
50
+ profile의 `cordis.yml`에 플러그인을 추가합니다:
51
+
52
+ ```yaml
53
+ - id: dsh-perm-gate
54
+ name: dsh-perm-gate
55
+ config:
56
+ rulesFile: ./permissions.yaml # 생략 시 defaultAction으로 폴백
57
+ dshHome: $DSH_HOME # 보호 대상 검사의 고정 루트
58
+ defaultAction: ask # allow | ask | deny
59
+ ```
60
+
61
+ [examples/permissions.example.yaml](./examples/permissions.example.yaml)에서 시작한 뒤
62
+ profile을 다시 불러오세요.
63
+
64
+ ## 업그레이드
65
+
66
+ ```sh
67
+ dsh plugin --profile web update dsh-perm-gate
68
+ ```
69
+
70
+ 그다음 패치 파일을 다시 읽도록 profile을 재적용합니다:
71
+
72
+ ```sh
73
+ dsh profile reload --profile web
74
+ ```
75
+
76
+ ## 분리된 플러그인에서 이전하기
77
+
78
+ `dsh-perm-gate`는 `dsh-permission-rules`, `dsh-auto-mode`, `dsh-auto-review`,
79
+ `dsh-movein-permissions`에 흩어져 있던 게이트·승인 심·선택적 분류기를 하나의
80
+ 패키지로 통합합니다.
81
+
82
+ 1. 기존 규칙 목록(deny / allow / ask)을 내보내 하나의 `permissions.yaml`로 합칩니다.
83
+ 2. 위 네 플러그인을 `cordis.yml`에서 제거하고 `dsh-perm-gate` 항목만 추가합니다.
84
+ 3. 해당 플러그인들이 제공하던 preset 재정의를 삭제합니다. `cordis.patch.yml`은
85
+ `permission.config.presets`를 **전체 교체**하므로, 다른 플러그인의 오래된
86
+ key 단위 패치가 Permissive / Auto 티어를 조용히 없앨 수 있습니다.
87
+ 4. profile을 다시 불러오고 아래의 `--list`로 검증합니다.
88
+
89
+ ## 검증
90
+
91
+ ```sh
92
+ # 로드된 규칙 세트 요약(Harness 불필요)
93
+ dsh-perm-gate --rules permissions.yaml --list
94
+
95
+ # 단일 호출 dry-run
96
+ dsh-perm-gate --rules permissions.yaml --tool bash --args '{"command":"pnpm install"}'
97
+ ```
98
+
99
+ `--list` 출력 예시:
100
+
101
+ ```json
102
+ {
103
+ "rulesFile": "/abs/path/permissions.yaml",
104
+ "defaultAction": "ask",
105
+ "ruleCount": 8,
106
+ "permissive": false,
107
+ "permissiveStrategies": { "trustAutoAllow": true, "alwaysConfirm": false, "llmAssist": false }
108
+ }
109
+ ```
110
+
111
+ UI의 **설정 → 플러그인 → Permissive 승인 티어**에 스위치 하나와 백엔드 전략 토글
112
+ 세 개가 표시되어야 합니다.
113
+
114
+ ## 제거
115
+
116
+ ```sh
117
+ dsh plugin --profile web remove dsh-perm-gate
118
+ dsh profile reload --profile web
119
+ ```
120
+
121
+ 플러그인을 제거하면 패치 기여도 사라지므로 Permissive 티어가 세션 권한 선택기에서
122
+ 다시 사라집니다.
123
+
124
+ ## 문제 해결
125
+
126
+ **권한 선택기에 Permissive 티어가 없습니다.**
127
+ DSH 번들 패치는 `permission.config.presets`를 key 단위로 병합하지 않고 **전체 교체**
128
+ 합니다. profile을 다시 불러와 `cordis.patch.yml`을 재적용하고, 더 늦게 로드되는
129
+ 플러그인이 `presets`를 덮어쓰지 않는지 확인하세요.
130
+
131
+ **규칙 파일이 있는데 `--list`가 `ruleCount: 0`을 표시합니다.**
132
+ `rulesFile`은 플러그인 디렉터리가 아니라 Harness 프로세스의 CWD에서 해석됩니다.
133
+ 절대 경로를 쓰거나 셸의 CWD를 확인하세요. 잘못된 문서는 로드 시 loud-fail하며
134
+ 조용히 비활성화되지 않습니다.
135
+
136
+ **`llmAssist`가 동작하지 않습니다.**
137
+ `classifierEndpoint`, `classifierModel`, `classifierApiKey`가 필요합니다
138
+ (**설정 → 플러그인 → Permissive 승인 티어** 또는 `cordis.yml`에서 지정).
139
+ 값이 없거나 네트워크 오류가 나면 사람 승인 심으로 폴백합니다. 설계상 fail-closed입니다.
140
+
141
+ **설정 카드에 "설정 네임스페이스를 사용할 수 없습니다"가 표시됩니다.**
142
+ 플러그인이 현재 profile에 조립되지 않았습니다.
143
+ `dsh plugin --profile web add dsh-perm-gate`를 실행하고 다시 불러오세요.
144
+
145
+ **`ja` / `ko` 선택 시 `locale "<id>" is not registered` 오류가 납니다.**
146
+ 공식 DSH의 `LocaleRuntime`은 `zh` / `en`만 노출합니다.
147
+ [한국어 README](./README.ko.md)의 호환성 안내를 참고하세요.
148
+
149
+ ## 라이선스
150
+
151
+ [MIT](./LICENSE)
package/INSTALL.md ADDED
@@ -0,0 +1,154 @@
1
+ # Installation guide
2
+
3
+ - [English README](./README.md)
4
+ - [中文 README](./README.zh.md)
5
+ - [日本語 README](./README.ja.md)
6
+ - [한국어 README](./README.ko.md)
7
+ - [Installation guide](./INSTALL.md)
8
+ - [中文安装指南](./INSTALL.zh.md)
9
+ - [日本語インストールガイド](./INSTALL.ja.md)
10
+ - [한국어 설치 안내](./INSTALL.ko.md)
11
+ - [Changelog](./CHANGELOG.md)
12
+ - [日本語 changelog](./CHANGELOG.ja.md)
13
+ - [한국어 changelog](./CHANGELOG.ko.md)
14
+
15
+ `dsh-perm-gate` version **0.1.0**. Continue with the [README](./README.md) for the
16
+ decision chain, the rules file format and the Permissive tier.
17
+
18
+ ## Requirements
19
+
20
+ - An existing [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) installation.
21
+ - Node.js **>= 20** (see `engines` in `package.json`).
22
+ - The `dsh` CLI on your `PATH`.
23
+ - A profile to install into — the browser half only ships for the `web` profile
24
+ (`dsh.client.platform = "web"` in `package.json`).
25
+
26
+ ## Install with the official CLI
27
+
28
+ ```sh
29
+ dsh plugin --profile web add dsh-perm-gate
30
+ ```
31
+
32
+ This pulls the published package, applies its `cordis.patch.yml` (the Permissive
33
+ session tier plus the plugin entry) and assembles both halves.
34
+
35
+ ## Install from source
36
+
37
+ ```sh
38
+ git clone https://github.com/drscrewdriver/dsh-perm-gate.git
39
+ cd dsh-perm-gate
40
+ npm install
41
+ npm run build # tsc -> lib/*.js + lib/*.d.ts, tsdown -> lib/client.js
42
+ dsh plugin --profile web add .
43
+ ```
44
+
45
+ `npm run build` is also the `prepublishOnly` step, so publishing never ships a
46
+ stale `lib/`.
47
+
48
+ ## Enable and configure
49
+
50
+ Add the plugin to your profile's `cordis.yml`:
51
+
52
+ ```yaml
53
+ - id: dsh-perm-gate
54
+ name: dsh-perm-gate
55
+ config:
56
+ rulesFile: ./permissions.yaml # optional; omit to fall back to defaultAction
57
+ dshHome: $DSH_HOME # root pinned for protected-target checks
58
+ defaultAction: ask # allow | ask | deny
59
+ ```
60
+
61
+ Start from [examples/permissions.example.yaml](./examples/permissions.example.yaml),
62
+ then reload the profile.
63
+
64
+ ## Upgrade
65
+
66
+ ```sh
67
+ dsh plugin --profile web update dsh-perm-gate
68
+ ```
69
+
70
+ Then re-apply the profile so the patch file is re-read:
71
+
72
+ ```sh
73
+ dsh profile reload --profile web
74
+ ```
75
+
76
+ ## Migrate from the split plugins
77
+
78
+ `dsh-perm-gate` merges the gate, the approval seam and the (optional) classifier
79
+ that used to live across `dsh-permission-rules`, `dsh-auto-mode`, `dsh-auto-review`
80
+ and `dsh-movein-permissions`.
81
+
82
+ 1. Export your existing rule lists (deny / allow / ask) and merge them into one
83
+ `permissions.yaml` document.
84
+ 2. Remove the four plugins from `cordis.yml` and add the single `dsh-perm-gate`
85
+ entry above.
86
+ 3. Delete any preset overrides those plugins contributed — `cordis.patch.yml`
87
+ **replaces** `permission.config.presets` wholesale, so stale per-key patches
88
+ from other plugins can silently drop the Permissive or Auto tier.
89
+ 4. Reload the profile and verify with `--list` (below).
90
+
91
+ ## Verify
92
+
93
+ ```sh
94
+ # summarize the loaded ruleset (no harness needed)
95
+ dsh-perm-gate --rules permissions.yaml --list
96
+
97
+ # dry-run one call
98
+ dsh-perm-gate --rules permissions.yaml --tool bash --args '{"command":"pnpm install"}'
99
+ ```
100
+
101
+ Expected `--list` output shape:
102
+
103
+ ```json
104
+ {
105
+ "rulesFile": "/abs/path/permissions.yaml",
106
+ "defaultAction": "ask",
107
+ "ruleCount": 8,
108
+ "permissive": false,
109
+ "permissiveStrategies": { "trustAutoAllow": true, "alwaysConfirm": false, "llmAssist": false }
110
+ }
111
+ ```
112
+
113
+ In the UI, **Settings → Plugins → Permissive approval tier** should render one
114
+ switch plus the three backend strategy toggles.
115
+
116
+ ## Uninstall
117
+
118
+ ```sh
119
+ dsh plugin --profile web remove dsh-perm-gate
120
+ dsh profile reload --profile web
121
+ ```
122
+
123
+ Removing the plugin also removes its patch contribution, so the Permissive tier
124
+ disappears from the session permission picker again.
125
+
126
+ ## Troubleshooting
127
+
128
+ **The Permissive tier is missing from the permission picker.**
129
+ The DSH bundle patch replaces the whole `permission.config.presets` map instead of
130
+ merging per key. Reload the profile so `cordis.patch.yml` is re-applied, and make
131
+ sure no later plugin overwrites `presets`.
132
+
133
+ **`--list` reports `ruleCount: 0` although my rules file exists.**
134
+ `rulesFile` is resolved against the process CWD of the harness, not the plugin
135
+ directory. Prefer an absolute path or confirm the shell CWD. A malformed document
136
+ fails loud at load — it is never silently disabled.
137
+
138
+ **`llmAssist` never fires.**
139
+ It needs `classifierEndpoint`, `classifierModel` and `classifierApiKey` (set them
140
+ in **Settings → Plugins → Permissive approval tier** or in `cordis.yml`). Any
141
+ missing value or network error falls back to the human seam — the gate is
142
+ fail-closed by design.
143
+
144
+ **Settings card shows "Settings namespace unavailable".**
145
+ The plugin is not assembled into the active profile. Run
146
+ `dsh plugin --profile web add dsh-perm-gate` and reload.
147
+
148
+ **Selecting `ja` / `ko` fails with `locale "<id>" is not registered`.**
149
+ Official DSH exposes only `zh` / `en` through `LocaleRuntime`. See the
150
+ compatibility note in the [README](./README.md).
151
+
152
+ ## License
153
+
154
+ [MIT](./LICENSE)