# dsh-auto-review-jev [简体中文](README.md) | English
A DeepSeek Harness approval guardian: permission requests are decided by a reviewer model before they ever reach you.
Install · Quick start · How it works · Configuration · System One · Policy · Trust boundary · Verification
> [!NOTE] > This is a fork of [`gbthui/dsh-auto-review`](https://github.com/gbthui/dsh-auto-review) (Apache-2.0). The reviewer seam, evidence pipeline, circuit breaker and audit sink are upstream work; this fork adds the **System One decision-API protocol**, the **`onLowConfidence` policy**, the **`allowRules` pre-approval whitelist** and a settings-page editor for both. ## Why this fork | | upstream `dsh-auto-review` | this fork | | --- | --- | --- | | Reviewer protocol | chat completion (`/chat/completions`) | **chat completion or System One decision API** (`POST {baseURL}/systemone`, one call, two parallel choice questions) | | Backends | any OpenAI-compatible endpoint | + **TypeSafe Jev**, **SiliconFlow `systemone`**, **self-hosted Laya** (loopback needs no key) | | Uncertain reviewer | deny | **`policy.onLowConfidence: deny \| defer`** — defer hands the ask to the human instead of a silent deny | | Repeated asks | every ask goes to the reviewer | **`policy.allowRules`** pre-approves exact tool + operation prefixes, with `policy.allowDangerFullAccessRules` gating unsandboxed grants | | Settings page | reviewer fields | reviewer **and** policy (confidence threshold, low-confidence action, allow rules) | ## Install The plugin lives in the **web** profile. Pick one source: ```bash # 1) release tarball (prebuilt, no build step, no approval to run build scripts) npx @deepseek-ai/dsh plugin --profile web add \ https://github.com/xlennart/dsh-auto-review-jev/releases/download/v0.2.0-jev.0/dsh-auto-review-jev-0.2.0-jev.0.tgz # 2) straight from git npx @deepseek-ai/dsh plugin --profile web add https://github.com/xlennart/dsh-auto-review-jev.git # 3) from a local checkout (development) npx @deepseek-ai/dsh plugin --profile web add /path/to/dsh-auto-review-jev ``` A bundle is loaded **when the profile process starts**, so restart the profile (for the desktop app: quit from the tray and start it again; for the CLI: stop and re-run `npx @deepseek-ai/dsh web`) — a running host will not pick up a newly installed or newly rebuilt plugin. Verify inside a session: ```text /auto-review status ``` It prints whether the guardian is armed, which endpoint/model answers, and where the audit file is. ## Quick start The plugin is enabled by default and, with no reviewer configured, uses the **current session model** — nothing to set up. To point it at a dedicated System One backend: ```yaml # ~/.dsh/settings.yaml dsh-auto-review: reviewer: protocol: systemone # chat (default) | systemone baseURL: https://api.typesafe.ai/v1 model: jev-latest apiKeyFile: ~/.dsh/reviewer.env # KEY=VALUE file; apiKey / apiKeyEnv also work systemone: confidenceThreshold: 0.8 # decision answers below this are not trusted policy: onLowConfidence: defer # deny (default) | defer to the human ``` Everything is also editable in **Settings → dsh-auto-review** in the Web UI. ## How it works ```mermaid flowchart TD A[Agent requests an operation the sandbox forbids] --> B{guardian armed?} B -- no --> H[Interactive approval: the human] B -- yes --> C[Evidence: tool call, sandbox state, read-only facts, bounded context] C --> R{policy.allowRules hit?} R -- yes --> P[allow once] R -- no --> D[Reviewer: systemone decision API or chat completion] D --> V{strict verdict parser} V -- allow --> P V -- deny --> X[rejected + denial notice injected for the agent] V -- low confidence --> W{policy.onLowConfidence} W -- deny --> X W -- defer --> H V -- critical risk --> X P --> Z[the operation is retried once] ``` * **The reviewer only substitutes for the approval prompt.** The plugin never changes sandbox configuration and never widens a sandbox on its own: it answers an ask the harness has already raised. * **Critical risk always denies**, whatever the decision answer said. * **Reviewer errors fail closed** (`policy.denyOnReviewerError: true`). * A **circuit breaker** stops an agent that keeps proposing variants of a denied action. * Denials are injected into the conversation as a notice with a producer-owned source kind (`plugin:dsh-auto-review`), so the transcript stays valid for the v4 session format. ## Configuration Settings segment: `dsh-auto-review`. Full reference: [`docs/configuration.md`](docs/configuration.md). ### Reviewer | Key | Default | Notes | | --- | --- | --- | | `protocol` | `chat` | `chat` = OpenAI-compatible completion, `systemone` = System One decision API | | `baseURL` | `''` | empty + `chat` = current session model; empty + `systemone` = SiliconFlow | | `model` | `''` | empty + `systemone` = `Kev-4b` (SiliconFlow provisional default) | | `apiKey` / `apiKeyEnv` / `apiKeyFile` | `''` | any one of the three; loopback endpoints need none | | `timeoutMs` | `24000` | per reviewer call | | `thinking` | `default` | `off` for backends that reject thinking | | `systemone.confidenceThreshold` | `0.6` | decision answers below this are not trusted (0.5–1) | | `factFinding.enabled` / `maxRounds` / `maxFacts` | `true` / `2` / `3` | read-only fact tools the reviewer may call | | `factFinding.content.enabled` / `maxBytes` | `false` / `4096` | whether file **content** may be attached to the ask | ### Policy | Key | Default | Notes | | --- | --- | --- | | `enabled` | `true` | master switch (`/auto-review on │ off`) | | `tools` | `[]` | restrict which tools the guardian reviews | | `allowRules` | `[]` | pre-approval whitelist: `{ tool, operations[], escalationTarget }` | | `allowDangerFullAccessRules` | `false` | must be `true` before a rule may grant `danger-full-access` | | `onLowConfidence` | `deny` | `deny` (fail closed) or `defer` (ask the human) | | `denyOnReviewerError` | `true` | reviewer crash/timeout ⇒ deny | | `context.enabled` / `maxMessages` / `maxChars` | `true` / `10` / `6000` | bounded conversation context for the reviewer | | `breaker.consecutiveDenyLimit` / `windowDenyLimit` | `3` / `10` | trip after repeated denials | | `audit.enabled` / `path` / `includeToolInput` | `true` / `~/.dsh/auto-review-audit.jsonl` / `false` | one JSON line per decision | ## System One decision API reviewer `protocol: systemone` turns a review into **one** decision-API call: ```http POST {baseURL}/systemone { "model": "