accpowered/dsh-auto-review

LLM approval answerer for DeepSeek Harness: deterministic filter + clean-context LLM review for sandbox escalations (requires the patched core, patches included)

项目介绍Project Overview

dsh-auto-review 是 DeepSeek Harness 的自动审批插件:在 approval 策略为 auto 时,对超出 workspace-write 的沙箱提权请求,先用确定性正则过滤,再交由小模型做隔离上下文安全评审,仅在不确定或出错时转人工,且默认失败即拒绝。适用于希望减少审批打断、又保留人工兜底的自动化会话。注意:它无法在原版 harness 上运行,必须先按序应用 core-patches 中的两个补丁并配置 auto-review 预设。

dsh-auto-review is a DeepSeek Harness plugin that auto-answers sandbox escalation approvals when the approval policy is auto. It first applies deterministic hardline/deny/allow regex rules, then sends gray-zone commands to a small reviewer model with a fixed prompt, temperature 0, and no conversation context; humans are asked only on UNSURE or configured fallbacks, and errors fail closed. Use it to reduce approval prompts while retaining human fallback. Caveat: it requires patched harness core patches and the auto-review permission preset; on stock upstream it stays inert.

或使用命令行安装(适合开发者)Or use CLI install (for developers)

命令行安装CLI Install

dsh plugin --profile web add github:accpowered/dsh-auto-review

accpowered/dsh-auto-review 加入你的 DSH 配置(web profile)即可启用。

READMEREADME

dsh-auto-review

English | 简体中文

License: MIT

LLM auto-review approval answerer for DeepSeek Harness: when a session's approval policy is 'auto', sandbox escalations beyond workspace-write (sandbox_permissions: "danger-full-access" + justification) are decided without a human prompt — a human is asked only when the reviewer is unsure, and every error path fails closed.

Two decision layers, in order:

  1. Deterministic filter — hardline (always-deny) + deny/allow regex rules over a normalized command (~/$HOME expansion, comment stripping, whitespace collapse, macOS private-path folding). A hardline or deny match rejects immediately; an allow match grants immediately; neither runs the LLM. Deterministic denials are FINAL — operator policy is never appealed.
  2. Clean-context LLM safety review — the gray zone goes to a small reviewer model with a fixed constant system prompt, temperature: 0, a single-word verdict (ALLOW / DENY / UNSURE), and a tight output cap. The user message carries ONLY the tool name, the justification, and the XML-wrapped command — never the conversation.

Appeal mode (context: 'appeal-user-prompts', the default): an LLM-voiced DENY is re-judged ONCE with the session's genuine user prompts attached as intent evidence — extracted deterministically (never LLM-summarized) from user/message events whose source kind is exactly 'user'. Appeals can only RELAX a denial, never tighten an allowance: they reduce false positives; they are not a detection upgrade.

The answerer registers with { prepend: true } on approval/request, so it runs before any human/machine channel, and delegates with next() whenever the effective policy is not 'auto' or the request carries no action. The reviewer is defense-in-depth against an honest-but-wrong model, never a sandbox-widening mechanism: workspace-write remains the boundary until a grant lands. An optional consecutive-denial circuit breaker (denialBreakerThreshold) short-circuits retry loops before any further LLM cost.

⚠ Requires a patched harness core

This plugin cannot run on stock upstream deepseek-harness. It needs three patched-core surfaces, shipped in core-patches/ as two git patches with a rebase guide (authored against upstream base commit 47f943859b, merge PR #2519):

  • 0001-approval-auto-policy-and-escalation-action.patch — the 'auto' approval policy, ApprovalRequest.action, ApprovalService.effectivePolicyFor, and the tool/sandbox/permission-presets wiring that carries the escalation action.
  • 0002-llm-auto-review-request-purpose.patch — the 'auto-review' LLM request purpose.

Apply them with git am (or git apply) in order after syncing upstream; if upstream conflicts, resolve and regenerate — see core-patches/README.md.

On vanilla upstream the plugin is deliberately inert: the policy gate never resolves to 'auto', so every escalation lazily delegates (next()) to the normal human answerers. Nothing breaks, nothing is auto-decided — but you get no auto-review until the patched core is in place.

Install

Prerequisites: a patched harness build (above), and the profile's permission presets must include the auto-review preset (sandbox: workspace-write + approval: auto) — patch 0001 adds it to the harness's permission-presets package.

From GitHub (builds on install via its prepare script; pnpm will ask you to allow the build once):

dsh plugin --profile web add github:accpowered/dsh-auto-review

If pnpm prints an allowBuilds prompt, add the printed key under allowBuilds in the profile's pnpm-workspace.yaml and re-run the add — this is install-time code execution permission, so only allow sources you trust (pinning a commit, github:accpowered/dsh-auto-review#<sha>, is recommended).

From a local checkout:

dsh plugin --profile web add ./dsh-auto-review

Restart dsh web (or your profile). The bundle patch (cordis.patch.yml) inserts one host row with a default reviewer route (deepseek-official / deepseek-v4-flash). To use a different reviewer, restate the row in your profile's cordis.patch.ymlprovider and model are required and a patch replaces the row's whole config:

- id: auto-review
  name: dsh-auto-review
  config:
    provider: my-provider      # any registered LLM route
    model: my-small-model

Configuration

All knobs (composition = the cordis.patch.yml row config; user = live override through the auto-review settings namespace):

Key Default Composition User-overridable Purpose
provider — (required) Reviewer route (a registered provider)
model — (required) Reviewer model id on that route
hardline shipped list Always-denied regex patterns; never bypassed while policy is auto
deny shipped list Configurable deny regex patterns
allow shipped list Configurable allow regex patterns (conservative, side-effect-free only)
maxTokens 512 Reviewer output-token cap (single-word verdict + headroom)
timeoutMs 15000 End-to-end reviewer deadline (ms)
onError deny Reviewer-failure fallback: deny (fail closed) or ask (human)
onUnsure ask UNSURE-verdict fallback: ask (human) or deny
denialBreakerThreshold 0 (off) Consecutive-denial circuit breaker
context appeal-user-prompts appeal-user-prompts or minimal (command alone, v1 behavior)
appealMaxPrompts 0 (unbounded) Appeal budget: newest user prompts attached (first prompt exempt)
appealMaxChars 0 (unbounded) Appeal budget: total user-prompt characters attached

hardline, maxTokens, and timeoutMs are composition-only by design. The shipped filter defaults are documented in src/index.ts (DEFAULT_HARDLINE_PATTERNS / DEFAULT_DENY_PATTERNS / DEFAULT_ALLOW_PATTERNS).

Live user-layer overrides

User-tunable keys live in the auto-review settings namespace (registered through installSettingsSection; the namespace name stays auto-review so existing user settings documents keep applying). The composition entry is the base layer; a committed user-layer change re-resolves and recompiles the rule patterns on the very next decision — no restart. A write carrying an invalid regex is refused at the settings seam, so a bad pattern can never reach the compiled filter.

Uninstall

dsh plugin --profile web remove dsh-auto-review

The answerer and the settings section detach with the plugin fiber. Log-only auto-review/decision events already on session logs are left untouched, and sessions on the auto-review preset fall back to the human answerers.

Development

pnpm install
pnpm build       # tsc declarations (lib/types) + tsdown (lib/index.js)
pnpm test        # vitest: filter/verdict/appeal flows, settings lifecycle (local approval stub)

Layout: src/index.ts (the whole plugin — answerer, config schema, settings section, exported pure functions), tests/auto-review.spec.ts + tests/stubs.ts (the stub replicates the patched ApprovalService's dispatch semantics; the npm rc.1 package predates the 'auto' policy), core-patches/ (the two required core patches + rebase guide).

License

MIT

上一个 Prev dsh-deck 下一个 Next dsh-devtools