New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

dsh-auto-review

Package Overview
Dependencies
Maintainers
1
Versions
43
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dsh-auto-review

Second-model AI auto-review for DeepSeek Harness approval requests: a read-only reviewer subagent decides allow/deny on the approval answerer chain, with fail-closed fallback and full session-log audit.

latest
Source
npmnpm
Version
0.13.7
Version published
Weekly downloads
505
-77.95%
Maintainers
1
Weekly downloads
 
Created
Source

🤖 dsh-auto-review

Gitee dshfind OpenSSF Scorecard

Second-model AI approval for DeepSeek Harness — a read-only reviewer subagent decides allow/deny on the approval chain, fail-closed by default.

When an action crosses the sandbox boundary, a second model reads the evidence and returns a verdict with a reason — so humans approve nothing while nothing unsafe slips through.

Official repository. This is the only official repository of dsh-auto-review, maintained by PerryLink. Same-name repositories under other accounts are not affiliated.

License DSH plugin dsh-doctor DSH Market Node CI Version npm version npm downloads

English · 简体中文 · Español · Português · हिन्दी

dsh plugin --profile <name> add dsh-auto-review

📖 Ecosystem knowledge base — measured data, not marketing: plugin development guide · plugin-selection data · maintenance criteria.

Install & uninstall

  • git channel (latest main): dsh plugin --profile web add github:PerryLink/dsh-auto-review — the isolated prepare build needs the single allowBuilds: { esbuild: true } key the dsh CLI prints for dsh-auto-review.
  • npm channel (published releases): dsh plugin --profile web add dsh-auto-review.
  • 1024 store channel: npm i -g dsh1024 once, then dsh1024 plugin --profile web add dsh-auto-review (counts toward the deepseek1024.com install ranking).
  • tarball channel: pnpm pack in this repo, then dsh plugin --profile web add ./dsh-auto-review-<version>.tgz.
  • uninstall: dsh plugin --profile web remove dsh-auto-review (or remove the row from the profile patch).
  • native build scripts: when dsh plugin add stops at ERR_PNPM_IGNORED_BUILDS for koffi / node-pty (pulled in by the eval harness), run pnpm approve-builds to approve those build scripts.

⭐ 如果它帮到了你

这个插件是 DSH 插件家族的一员(95 个,全部 Apache-2.0)。如果你在用,给个 star —— 它不会解锁任何功能,但会让下一个人在搜索里更容易找到它。

English: part of a 95 plugin family for DeepSeek Harness. If it is useful, a star helps the next person find it — nothing is gated behind it.

What is dsh-auto-review?

Second-model AI approval for DeepSeek Harness — a read-only reviewer subagent decides allow/deny on the approval chain, fail-closed by default.

When an action crosses the sandbox boundary, a second model reads the evidence and returns a verdict with a reason — so humans approve nothing while nothing unsafe slips through.

Terminal demo of dsh-auto-review: dsh-auto-review — standalone MCP path: deterministic deny, then cache replay

Animated terminal demo of dsh-auto-review

The same run, animated.

Compatibility

SurfaceStatus
HarnessDeepSeek Harness dsh-v0.2.1-rc.2 (verified 2026-10-18): engines.dsh >=0.2.1-0 <0.3.0; the P0 compatibility paths have regression tests.
Node^22.19.0 || >=24.0.0
PlatformsAll (host answerer; optional Web review panel via the session-projection capability)
ModelAny (the reviewer inherits the session agent's route; reviewerModel overrides)

What you get

dsh-auto-review puts a second model on the approval/request answerer chain:

  • Official seam — an answerer that claims only the requests it owns (ai policy) and delegates everything else via next(); the human approval flow is never short-circuited.
  • Read-only reviewer subagent — a one-shot fork with a read/glob/grep tool allow-list returns a structured verdict { decision, reason, riskLevel }. Reviewer asks are recognized by identity and delegated; maxDepth + the allow-list keep the reviewer non-delegating.
  • Fail closed — reviewer crash, timeout, or schema mismatch resolves through fallbackPolicy (default rejected); a deny verdict feeds its reason back to the calling model.
  • Config-driven routing — per-tool policies (ai/human/never) plus regex risk rules, all changeable from cordis.yml.
  • Deny reasons reach the model — the reviewer's reason is injected into the denied tool result (callId-linked); fallback and never-policy rejections inject auditable markers too ([auto-review] / [auto-review-fallback] / [auto-review-never]).
  • Full audit trail — log-only autoReview/verdict + autoReview/rejection session events (envelope ignorable: true) plus an optional invariant companion enforcing marker ⟺ event.
  • Safety knobs — a rejection circuit breaker (3 consecutive denials, or 6 of the last 10 verdicts, per turn), a risk-level policy, a one-shot /auto-review approve override, and a never-policy hard disable that explains itself to the model.
  • Optional reviewer context — a bounded compact transcript (contextBudget) plus a Codex-style Markdown ruling policy (reviewerPolicyText).

Every decision reconstructs from the session log: approval/asked → autoReview/verdict (or autoReview/rejection) → approval/decided.

Why a second model instead of rules?

Pattern-based auto-approvers decide before dispatch, with no evidence. dsh-auto-review gives the decision to a reviewer subagent that reads the actual workspace (through its read-only tool face), the already-streamed tool-call arguments (sensitive values redacted), the request reason, and your risk rules — then returns a structured verdict. A deny verdict feeds its reason back to the calling model, so the agent learns why instead of retrying blindly.

Quick start

dsh plugin --profile web add github:PerryLink/dsh-auto-review
# 1. install the bundle into your profile
dsh plugin --profile web add github:PerryLink/dsh-auto-review

# or from npm (published releases)
dsh plugin --profile web add dsh-auto-review

# 2. restart and verify the row
dsh --profile web --dump-config | grep -A4 'id: auto-review'

Out of the box the shipped patch AI-reviews bash and write; every other tool (including edit — in-place modification) delegates to the human chain. Add edit: ai explicitly if you accept in-place edits without a human in the loop.

Configuration

All tunables are Schemastery Config fields (changeable from cordis.yml). An id-targeted override replaces the whole row — restate every key you need.

KeyDefaultMeaning
enableByDefaulttrueSessions start with auto-review enabled; /auto-review on|off writes a durable override that beats this
toolsPolicy.defaulthumanPolicy for unlisted tools (delegate to the human answerer)
toolsPolicy.overrides{}Per-tool policy: ai / human / never
riskRules[]{pattern, policy, field?} matched before the tool table; field selects reason (default), toolName, or arguments
reviewerProviderforkSubagent provider for the reviewer (in-process fork backend)
reviewerPreset(none)Read-only Agent Preset id; required when the host exposes startActivation (0.2.1+) instead of toolFilter
reviewerModel(inherit)Reviewer model id; unset inherits the session agent's route
reviewerModelProvider(inherit)LLM provider route for reviewerModel; unset inherits the session agent's provider
reviewerTimeoutMs60000Verdict deadline; on expiry the fallback policy applies
reviewerTools[read, glob, grep]The reviewer child's tool allow-list (must be non-empty)
fallbackPolicyrejectedReviewer failure: rejected (fail closed) / delegate / allow-once
maxReviewsPerTurn10Real AI-verdict budget per open turn; beyond it, requests delegate
maxFailuresPerTurn10Reviewer-failure budget per open turn
reasonMaxChars2000Cap for reviewer reasons and the redacted argument preview
reviewerGuidance(none)Optional advisory guidance appended to the reviewer prompt
reviewerPolicyText(none)Markdown ruling policy injected into the reviewer prompt (Codex-style)
denyGuidance(anti-circumvention text)Guidance appended to every injected deny reason
contextBudget{turns: 2, maxChars: 4000}Compact transcript budget for the reviewer prompt (the open turn plus the one before it); turns: 0 disables the section — and a blind reviewer denies user-authorized actions, so the runtime warns when 0 meets an ai policy. The character budget is spent on the most recent lines
riskPolicy{maxAutoAllow: high, onHighRisk: delegate}allow verdicts above maxAutoAllow delegate or deny
circuitBreaker{consecutiveDenies: 3, windowDenies: 6, windowSize: 10, action: delegate}Rejection circuit breaker
overrideTtlMs300000How long a /auto-review approve override stays usable
verdictCacheTtlMs60000Reuse a recent verdict for an identical tool + arguments fingerprint; 0 disables the cache. Only applies with contextBudget.turns: 0 — a transcript-dependent verdict is not replayable from tool + arguments alone
verdictCacheMaxEntries256Maximum cached fingerprints before oldest-eviction
languageenUI language of the /auto-review command output (en | zh)
allowUnmarkedAuditfalseForce session-log audit on hosts that drop the ignorable marker or fail-closed on unknown event types (host 0.1.2-rc.1+) (dangerous: unmarked events make sessions unresumable elsewhere); default is detect-and-degrade (adapted 2026-09-02, re-verified against 0.1.5-rc.2 on 2026-09-11): the session envelope keeps its ignorable field for stored-log read compatibility only - Session.append still cannot stamp it, so audit-gate behavior is unchanged.

Example (annotated full form: fixtures/config/config-full.yaml):

- insert:
    - id: auto-review
      name: dsh-auto-review
      config:
        toolsPolicy:
          overrides: { bash: ai, write: ai }
        riskRules:
          - pattern: '([Rr][Mm]\s+(-[a-z]+\s+)*/|[Gg][Ii][Tt]\s+push\s+--force)'
            policy: never
          - pattern: 'write'
            policy: never
            field: toolName
        reviewerTimeoutMs: 30000
        fallbackPolicy: delegate
        riskPolicy: { maxAutoAllow: medium, onHighRisk: delegate }
        circuitBreaker: { consecutiveDenies: 3, windowDenies: 6, windowSize: 10, action: delegate }

Where the config actually comes from

~/.dsh/settings.yaml is NOT a config source for this plugin. An auto-review: block there has no effect and produces no warning: like every DSH function plugin, dsh-auto-review receives its Config from the row the loader mounts it with — the profile's cordis patch layer. (Some other DSH plugins additionally read the settings service, so the inconsistency is easy to trip over, and the symptom is indistinguishable from the reviewer simply denying.)

Put the configuration in your profile's cordis.patch.yml. An id-targeted override replaces the whole config row, so restate every key you need — dropping toolsPolicy silently returns bash/write to the schema default human and the reviewer stops running at all:

- id: auto-review
  config:
    toolsPolicy:
      overrides: { bash: ai, write: ai }
    contextBudget: { turns: 4, maxChars: 8000 }

Tools & surfaces

SurfaceKindNotes
auto-reviewanswererapproval/request waterfall answerer — claims ai-policy requests, delegates the rest via next()
/auto-reviewcommandon|off|status|approve [n] — durable per-session override, budgets, and cumulative statistics
deny-reason injectionlistenertools/post-execute — verdict / fallback / never reasons fed back to the denied tool result
autoReviewsession projectionFolded from the log-only autoReview/* events
Web review panelclientSession-header action: switch, budgets, statistics, recent verdicts, one-shot approve
dsh-evalCLIYAML-driven agent evaluation engine (bin/dsh-eval.mjs)
invariant companioninvariantdsh-auto-review/invariant (optional; needs the invariants service)

Session command

/auto-review on|off|status|approve [n]

on/off append the durable autoReview/state override (the fold survives restart/resume — replay IS the state) and inject a switch notice the model sees (logged as a user/message event). status reports the effective state, both per-turn budgets (AI verdicts and reviewer failures), a tripped circuit breaker when one is active, and the session's cumulative statistics (allows/denies/fallbacks/never rejects, mean duration, recent verdicts). approve [n] records a single-use autoReview/override for the n-th most recent denial (1 = most recent): the next same-tool review within overrideTtlMs carries the authorization as reviewer context — the reviewer still decides, and the override is consumed by that review regardless of its outcome.

Web review panel

In the Web GUI (web profile), the package contributes a session-header action (AI Review) that opens a panel with the session's auto-review state: the switch with on/off buttons (they execute /auto-review on|off), both per-turn budgets, cumulative statistics (including hard-disable rejections and cache hits), the circuit trip, the recent verdicts, and one-shot approve buttons for recent denials (they execute /auto-review approve [n]).

How it is wired:

  • The host registers an autoReview session projection (folded from the log-only autoReview/* events) and serves it through the session-projection channel.
  • The browser half is a client module (auto-discovered from the dsh.client declaration) registered on the conversation.session.header.actions seat.
  • No extra patch rows are needed: the panel loads whenever the plugin is installed in a profile whose web build provides the session-projection capability (the web profile does). Without that capability the panel reports itself unavailable; the answerer is unaffected.

The panel reads only whole projection values — it never receives the raw session event stream.

How it works

                       approval/request waterfall (answerer chain)
                        │
┌───────────────────────┴──────────────────────┐
│ dsh-auto-review answerer                     │
│  · session enabled?  · policy = ai?         │   no ── next() ──▶ human answerer (UI)
│  · risk rules → toolsPolicy → default       │
└───────────────────────┬──────────────────────┘
                        │ yes
                        ▼
        ┌───────────────────────────────────┐
        │ reviewer subagent (fork, one-shot)│
        │  · toolFilter: read/glob/grep     │
        │  · outputSchema: {decision,       │
        │    reason, riskLevel}             │
        │  · timeout + req.signal abort     │
        └───────────────┬───────────────────┘
                        │ verdict / failure (fail-closed fallback)
                        ▼
 allow → allowed-once        deny → rejected + reason injected into the
                                       denied tool result (callId-linked)
                        │   never → rejected + [auto-review-never] feedback
                        │            (hard disable, no reviewer runs)
                        ▼
 audit: approval/asked → autoReview/verdict | autoReview/rejection
        → approval/decided (session events, log-only, invariant-checked)

Composition order. The answerer runs at its registration position in the waterfall: if a human UI answerer is composed BEFORE the auto-review row, humans answer first and the reviewer only sees what is delegated downstream. Verify with dsh --profile <name> --dump-config and place the auto-review row before your human answerer rows when you want ai-policy tools routed to the reviewer first.

dsh-eval — agent evaluation engine

Beyond the approval reviewer, dsh-auto-review ships dsh-eval: a YAML-driven agent evaluation platform that runs real headless DSH sessions (one isolated agent + scratch workspace per case, the official Minimal persona as the baseline system prompt), collects the tool-call trace from the session event log, and evaluates structured assertions plus an optional second-model review — the same reviewer seam as the approval answerer.

# eval/cases/demo.yaml (abridged)
suite:
  name: my-suite
  cases:
    - id: math-output
      input: Solve 17 × 24 and reply with only the final number, nothing else.
      expect:
        output: { contains: "408" }
    - id: glob-trace
      seedFrom: '.'
      input: Use the glob tool with pattern "src/**" to list the source files…
      expect:
        toolCalls: [{ tool: glob, arguments: { contains: { pattern: "src" } } }]
        results: [{ tool: glob, contains: "index.ts" }]

Run it (a DeepSeek API key must be in the environment):

dsh-eval eval/cases --model deepseek-flash --timeout-ms 240000 --out .eval-reports

Assertion families

The expect block supports six assertion families; each assertion is evaluated independently and reports its own pass/fail with expected/actual values, so a failing case explains itself without a rerun.

FamilyDSL keysWhat it gates
Tool tracetoolCalls, toolCallsExact, noToolCalls, resultsordered tool-call sequence (subsequence with skips), exact name sequence, per-tool result (isError/contains/regex)
Output & budgetoutput, turnEnds, maxTokensfinal-output substring/regex, turn outcome, token budget
Prompt regressionpromptthe rendered system prompt must match a committed baseline (or a baselineFrom file); any drift is reported as a side-by-side diff, with allowedChanges regexes to whitelist intended edits
Stress metricsstressP99 step latency (maxP99Ms), worst time-to-first-token (maxTtftMs), aggregate token generation speed (minTokensPerSecond)
Fairnessbiasbias radar over the final output: per-category regex counts (categories), hard forbid patterns, maxHits/maxCategoryHits caps
Second-model reviewreviewa supplementary pass/fail verdict from the reviewer subagent (a separate layer, same seam as the approval reviewer)
- id: regression-gate
  input: Answer in one sentence.
  expect:
    prompt:
      baseline: "You are a helpful software engineer assistant."
      allowedChanges: ["copyright-year"]
    stress:
      maxP99Ms: 8000
      maxTtftMs: 3000
      minTokensPerSecond: 20
    bias:
      categories: { gender: ["[Hh]e is (un)?stable"] }
      forbid: ["[Ss]crew that"]
      maxCategoryHits: 0

CI gate: the process exits 0 only when every case of every suite passed — failing evaluations fail the build. Each case leaves a replayable session JSONL and a trace JSON beside report.md/report.json; assertion results (including the prompt side-by-side diff), token usage, stress/bias metrics, and the review verdict are all written into the report files.

- name: dsh-eval
  run: npx dsh-eval eval/cases --model deepseek-flash --timeout-ms 240000 --out .eval-reports
  env:
    DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}

dsh-eval differs from openai/codex-research: codex-research scores agent trajectories for research comparison; dsh-eval is a declarative pass/fail regression harness — YAML cases, structured trace/prompt/stress/bias assertions, an optional second-model review, and a CI exit code — for gating any DSH agent, not research ranking.

MCP server (standalone)

dsh-auto-review also ships a stdio MCP server (dsh-auto-review-mcp) so external MCP clients (Claude, Codex, …) can consume a deterministic review path without a harness. It speaks JSON-RPC 2.0 over newline-delimited JSON (NDJSON) — one JSON object per line, no Content-Length framing.

Boundary. The full reviewer needs the harness subagent seam and a second model, which a separate stdio process cannot reach. The standalone server is therefore deterministic rules + cache, no model review:

  • review_action reuses the same-fingerprint verdict cache (src/cache.ts) and the risk-rule / tool-policy resolution (src/config.ts): a never rule → deny; a cache hit on an identical tool + arguments fingerprint replays that verdict; anything else (ai needs a model, human needs a human) → fail-closed deny with reason: "standalone path, no model". It never allows an action a model did not already allow.
  • cache_stats reports hit/store counts and the TTL status.
ToolPurpose
review_action{tool, args?, reason?} → {decision, reason, riskLevel} — deterministic deny / cache replay
cache_stats{} → {hits, stores, size, ttlMs, enabled}

Run it directly:

# risk rules come from environment variables
export DSH_AUTO_REVIEW_RISK_RULES='[{"pattern":"rm -rf","policy":"never","field":"arguments"}]'
node bin/dsh-auto-review-mcp.mjs
# or, after npm install: npx dsh-auto-review-mcp

Environment config: DSH_AUTO_REVIEW_RISK_RULES (JSON array of {pattern, policy, field?}), DSH_AUTO_REVIEW_TOOLS_POLICY (JSON {default?, overrides?}), DSH_AUTO_REVIEW_CACHE_TTL_MS, DSH_AUTO_REVIEW_CACHE_MAX_ENTRIES.

Claude Desktop (claude_desktop_config.json) example:

{
  "mcpServers": {
    "dsh-auto-review": {
      "command": "npx",
      "args": ["-y", "dsh-auto-review-mcp"],
      "env": {
        "DSH_AUTO_REVIEW_RISK_RULES": "[{\"pattern\":\"rm -rf\",\"policy\":\"never\",\"field\":\"arguments\"}]"
      }
    }
  }
}

The server is read-only and deterministic: no network, no model, no writes.

Permissions & data

  • Permissions: the workshop manifest declares session:append, approval:answer, subagent:spawn, command:register, and tools:observe.
  • Data: nothing is stored on disk; the report ring buffer is in-memory and bounded. No network requests of its own.
  • Session log: autoReview/* events carry reviewer identity, verdict, reason, risk, and duration — appended with the envelope's ignorable: true marker so any build loads the log. Hosts whose Session.append predates the marker (every released rc line through 0.1.1-rc.2 — no release stamps it yet) are detected before the first append (peer-version pre-check); hosts 0.1.2-rc.1, 0.1.3-alpha.2, and 0.1.5-rc.2 keep the ignorable field on the envelope but Session.append offers no way to stamp it (its third parameter is SurfaceIntent for surface events only), and the persistence read path refuses unmarked unknown event types, so those lines — and unresolvable versions — also fail closed before any append. Audit then degrades to an in-memory mirror with marker-free feedback, so sessions stay loadable everywhere.

Security boundaries

  • The reviewer is a model. Its verdicts are advisory policy, not a security kernel; prefer human/never rules for irreversible operations.
  • Fail closed. Every abnormal path (provider missing, capability gaps, start rejection, timeout, non-completed stop reason, missing/malformed verdict, audit-correlation failure) resolves through fallbackPolicy, default rejected — and the rejection feeds an auditable reason back to the model. allow-once grants unconditionally; it exists only for unattended deployments whose admin accepts that risk.
  • Read-only reviewer. The reviewer's toolFilter allow-list (read/glob/grep) cannot write, edit, run bash, fetch the network, or delegate (maxDepth = its own depth). Its session log is persisted and auditable.
  • Context-isolated reviewer. The reviewer child's steps are filtered on the documented agent/pre-step seam: only its own prompt and its own read-only tool results enter them. Workspace instruction files (AGENTS.md / CLAUDE.md) and context-injecting plugins are dropped from the step this seam controls. The host's own runtime-context snapshot is re-admitted by the loop after agent/pre-step; the firewall does not remove it, so the reviewer sees it. This holds under EITHER subagent provider. The filter is an allow-list over message SOURCES, so a plugin that declares a new source kind is dropped too.
  • Sensitive arguments are redacted (key-name matching: token, password, api_key, Authorization, credentials, private keys …) before entering the reviewer prompt, and a free-form string argument additionally passes an inline heuristic that masks the KEY=VALUE / KEY: VALUE / --flag VALUE spellings and Bearer/Basic schemes — which is how a secret usually appears in a shell call. The plugin never executes the reviewed arguments. Both passes are best-effort, not a secret scanner: a bare secret with no key next to it stays visible, so do not AI-review tools whose argument values you cannot afford to show a model.
  • Hard disables explain themselves. A never tool or risk rule rejects deterministically AND records a log-only autoReview/rejection event, then injects a [auto-review-never] marker into the denied tool result — the model learns the action is hard-disabled instead of retrying it (invariant-checked: marker ⟺ event).
  • Rejection circuit breaker. A run of denials in one turn trips the breaker (consecutiveDenies / windowDenies inside windowSize), recorded as a log-only autoReview/circuit event; later requests follow its action (delegate / reject / abort-turn).
  • Reviewer context is presented transcript. contextBudget feeds already-presented session content to the reviewer. With the default same-route reviewer model that content stays inside one provider; configure reviewerModel to a different provider only if you accept presenting that transcript to it.
  • never is one-way at this layer. A never tool or risk rule rejects before the human chain sees the request — a lockdown knob, not a default.

Known limitations

  • Two different exposures, two different answers — neither substitutes for the other. Injected context (workspace instruction files, third-party plugin injections) is injected fresh into any new agent session, so it reaches the reviewer identically under reviewerProvider: fork and reviewerProvider: spawn; the host runtime-context snapshot is re-admitted after the pre-step seam and is explicitly out of the firewall's claim — measured byte-identical across both on the same request. The agent/pre-step source filter closes the workspace/third-party half under either provider; it does not remove the host snapshot, which is re-admitted after the seam. spawn alone does NOT keep workspace instructions out of the reviewer. Separately, fork seeds the child with the delegating session's completed turns: that history is already the child's own log rather than a message entering a step, so the filter cannot touch it and only spawn avoids it, with the reviewer prompt's untrusted-transcript fence as the mitigation in between. In the two traces above the seeding produced no additional messages, so its practical impact is unquantified.
  • The reviewer needs a working LLM route (inherited by default); without one every review falls back per fallbackPolicy — never a silent grant.
  • reviewerTools names must exist as global tools in the profile; an unknown name fails the reviewer child loudly at the earliest point and falls back.
  • Risk rules match the request reason, the toolName, or the redacted call arguments per their field; other conditions belong in toolsPolicy.overrides.
  • The /auto-review approve override authorizes the next same-tool review, not the exact historical call; a different action on the same tool consumes it.
  • The verdict events are log-only; the Web review panel reads the folded autoReview projection (the raw event stream never reaches browser plugins).
  • autoReview/state and autoReview/verdict are appended with the envelope's ignorable: true marker on hosts that honor it, so any harness build loads the log — readers that do not know the out-of-repo types simply skip those records. On released rc hosts (rc.1–rc.8) the runtime detects the dropped marker and never writes these events (the in-memory mirror keeps the command, budgets, breaker, and approve working for the session); sessions already polluted by pre-0.5.1 versions can be repaired with scripts/repair-session-logs.mjs from dsh-permission-rules (its default target set covers all five autoReview/* event types).
  • The git channel needs the single allowBuilds key the dsh CLI prints for dsh-auto-review itself. The repo ships its own pnpm-workspace.yaml with allowBuilds: { esbuild: true }; typescript + tsdown are regular dependencies.
  • The optional invariant companion needs the invariants service (agent-spine compositions such as headless/ACP); the plain web profile does not provide it, so the row ships commented out in the bundle patch.
  • Andy8647/dsh-auto-approval — two-state allow/deny classifier on the tools/pre-execute waterfall with file-log audit. dsh-auto-review deliberately differs: official answerer chain, always delegates what it does not own, read-only second model with a structured verdict, deny reasons fed back to the model, session-log audit.
  • ACP automation bridge — one-shot machine decisions for its own ACP-owned agents. dsh-auto-review is session- and tool-policy-scoped for the interactive harness; it never infers durable grants.

Development

pnpm install                # node ^22.19 || >=24
pnpm run typecheck          # tsc: src + tests against the local harness checkout
pnpm test                   # vitest: 25 spec files
pnpm run build              # tsc declarations + tsdown bundles (lib/, incl. the client bundle)
pnpm run verify:self-contained
pnpm pack                   # the published tarball

Repository layout: src/index.ts (plugin contract) · src/config.ts (Schemastery schema + resolution) · src/runtime.ts (answerer, command, deny-reason injection) · src/review.ts (reviewer orchestration, prompt, sanitization) · src/events.ts (session-event vocabulary + folds) · src/audit.ts (host ignorable-marker capability detection) · src/projection.ts + src/projection-types.ts (the autoReview session projection) · src/invariant.ts (invariant companion) · src/eval/ (the dsh-eval engine) · eval/ (shipped evaluation composition) · bin/dsh-eval.mjs (CLI launcher) · src/client/ (browser half) · test/ · fixtures/.

Interoperability with other DSH plugins

Verified against DSH 0.2.0-rc.2 (the runtime this README ships for) and the high-star plugin set surveyed on 2026-10-05.

This plugin does not interfere with other plugins, including the widely installed high-star ones:

  • No tool-name collision. Every tool is namespaced; no bare name owned by a shipped tool or another plugin is registered.
  • No service-key collision. It provides autoReviewRuntime; that key is not a built-in seam and is not provided by any surveyed high-star plugin.
  • No slot collision. It registers no client slot key, so it cannot contend for a shadows-shipped-ui seat.
  • No HTTP route collision. It registers no webServer prefix.
  • No patch-layer collision. The bundle patch only inserts its own row; it never overrides a built-in row's config.
  • No global mutation. It does not patch prototypes, rewrite process.env, or replace the global fetch dispatcher.

Shared event listeners are non-interfering by construction. It observes the ordering-sensitive events agent/pre-step, approval/request, tools/post-execute with ctx.on() — Cordis's broadcast registration, where every listener runs and none can starve another. Every listener here delegates through next(), so the chain is never short-circuited, and a mutation is applied to the value next() produced rather than returned in its place:

  • agent/pre-step — also used by dsh-routing-suite (7000★, 7 listeners), modlens (4122★), dsh-purge (3317★), dsh-agent-teams (1923★), dsh-context (1849★).
  • tools/post-execute — also used by cc-safety-net (1576★).

Static evidence: dsh-plugin-doctor K10–K13 report pass for every check on this repository.

Topics

deepseek-harness, dsh, dsh-plugin, cordis, approval, auto-review, second-model, ai-safety, sandbox, subagent

Contributors

  • @PerryLink — creator and maintainer: the approval answerer, the reviewer subagent, risk policy and circuit breaker, the session-projection review panel, the invariant companion, dsh-eval, and the five-language docs.
  • @weipeng1999 — proposed independent reviewer provider/model routing (#11, discussion #12), which shipped as reviewerProvider / reviewerModel.
  • @alexchenzl — listed the plugin on the DSH plugin directory (#10).

This project is one of the 87 actively maintained DeepSeek Harness plugins from PerryLink. The family roster is 95 plugins in total — 5 frozen, 3 retired — and stays collapsed below so every README keeps a short first screen. Expand it to see every row, with the reason in the Status column.

Expand all 95 plugins
PluginOne-linerStatus
dsh-aqua-input-check水产养殖投入品记录核对(按投入品用量、休药期与起捕间隔核对记录自洽,仅提示差异,不作出定性结论)
dsh-archive-check档案归档完整性与保管期限核对(依据《档案法》及配套规定,仅提示差异,不作出定性结论)
dsh-auto-reviewSecond-model auto-review on the approval chain, fail-closed by default
dsh-autotierAutomatic strong/cheap model-tier routing with deterministic risk guards and a /tier command
dsh-background-agentsDurable background child agents with a Web UI sidebar, messaging and interrupt🚫 RETIRED — see the repo README
dsh-bid-ca-precheck投标文件符合性预检(按招标文件逐条核对响应情况,仅提示差异,不作出定性结论)
dsh-bid-qual-check投标人资格条件核对(按资格条件与证明材料核对逐条响应,仅提示差异,不作出定性结论)
dsh-budgetCost governance for DeepSeek Harness: budgets, carbon, and latency in one panel.🧊 FROZEN — see the repo README
dsh-cert-mcpRead-only MCP server exposing the certification registry: grades, snapshots and five-dimension evidence
dsh-checkpoint-rewindClaude Code /rewind-equivalent: snapshots, session forks, one-shot restore
dsh-claude-moveMigrate Claude Code sessions, memory, skills and CLAUDE.md into DSH🧊 FROZEN — see the repo README
dsh-clickCross-platform native desktop control for DeepSeek Harness — Windows first.
dsh-composer-historyTerminal-style input history for the web composer: arrows, Ctrl+R search
dsh-contract-stance合同条款立场台账核对(按立场、风险等级与退让底线核对台账自洽,仅提示差异,不作出定性结论)
dsh-customs-doc-check报关单证一致性核对(按公开的报关单填制规范核对单证间字段一致性,仅提示差异,不作出定性结论)
dsh-data-qualityDataset quality checks and citation cross-checks (the optional numeric bridge consumed here)
dsh-defendPrompt-injection, jailbreak, and secret-leak defense for DeepSeek Harness.🧊 FROZEN — see the repo README
dsh-demurrage-ledger滞箱费台账核对(按免箱期与费率核对超期天数与金额的自洽性,仅提示差异,不作出定性结论)
dsh-doublecheckEngineering-discipline guard: requirements grill, test gates, adversary review
dsh-drawUnified static-image generation routing for DeepSeek Harness.🧊 FROZEN — see the repo README
dsh-drill-script-check应急演练脚本核对(按阶段、响应分级、指挥与资源要素核对脚本齐备,仅提示差异,不作出定性结论)
dsh-eia-guide-check环评导则适用性核对(按要素、导则名称与执行标准核对台账自洽,仅提示差异,不作出定性结论)
dsh-emergency-plan应急预案要素齐备性与条款级页码定位(依据 GB/T 29639-2020 等公开文件,仅提示差异,不作出定性结论)
dsh-essay-rubric-check作文量表评分核对(按评分项、原文定位与分值算术核对评分自洽,仅提示差异,不作出定性结论)
dsh-evidence-check证据清单齐备性核对(按待证事实与证据要素核对清单自洽,仅提示差异,不作出定性结论)
dsh-export-ctl-check出口管制物项核对(按管制清单、最终用途与许可证核对台账齐备,仅提示差异,不作出定性结论)
dsh-fastRead-only performance diagnostics for DeepSeek Harness.
dsh-fmea-table-checkFMEA 分析表要素齐备性与风险顺序数一致性核对(按公开的 FMEA 方法标准核对表内自洽,仅提示差异,不作出定性结论)
dsh-forecast-penalty预测准确率考核核对(按准确率、门槛与考核单价核对考核费用的算术自洽,仅提示差异,不作出定性结论)
dsh-fund-researchDeterministic research reports for Chinese public mutual funds
dsh-githubGitHub PR/issues integration for DSH, every write gated by approval
dsh-gongwen-flow-check公文流转与办理时限核对(按公开的公文处理规范核对环节完整性与时限,仅提示差异,不作出定性结论)
dsh-gongwen-word-check公文格式要素核对(按公开的党政机关公文格式标准核对版头与主体要素,仅提示差异,不作出定性结论)
dsh-guard-plan-qc劳动保护与安全防护用品配置表核对(按公开的配备标准核对品名规格与配置数量,仅提示差异,不作出定性结论)
dsh-hazchem-check危险化学品临界量与重大危险源辨识核对(按储存量与临界量核对台账自洽,仅提示差异,不作出定性结论)
dsh-hazplan-checkHAZOP 分析表要素齐备性与偏差推导一致性核对(依据公开的危险与可操作性分析标准,仅提示差异,不作出定性结论)
dsh-hidden-risk-map安全隐患台账→《工贸企业重大事故隐患判定标准》(应急管理部令第10号)条款映射提示(仅提示差异,不作出定性结论)
dsh-hs-classify商品归类层级一致性核对(按章、品目、子目与商品编号的层级关系核对自洽,仅提示差异,不作出定性结论)
dsh-icd-rule-checkICD 合并编码与星剑号配对提示(依据 GB/T 14396-2016 与公开的 ICD 使用说明,仅提示差异,不作出定性结论)
dsh-industry-researchIndustry research orchestration that seals its deliverables through this plugin's ctx.researchReport.assemble
dsh-lawcite-adapter法条引用与文书要素核对(按名称、条号、原文与效力状态核对引用可核验性,仅提示差异,不作出定性结论)
dsh-layaLaya typed decisions (noul/choice/score) as a first-class Cordis service and model-visible tools
dsh-lc-doc-check信用证单据条款核对(按单据种类、份数、期限与不符点核对交单自洽,仅提示差异,不作出定性结论)
dsh-learning-gap-check能力差距与培养计划核对(按能力等级差、培养措施与完成期限核对台账闭环,仅提示差异,不作出定性结论)
dsh-libraryLocal document knowledge base for DeepSeek Harness.
dsh-local-aiLocal-model (Ollama) integration for DeepSeek Harness.
dsh-lsp-actionsLSP diagnostics, formatting, completion, code actions and rename over language servers
dsh-maskPII masking middleware: anonymize at the model boundary, restore at the display layer
dsh-mcp-panelRead-only MCP runtime panel: /mcp command + Settings tab with status, tools and errors
dsh-medrec-qc病案首页形式质控与逻辑矛盾提示(依据国卫办医发〔2016〕24号等公开文件,仅提示差异,不作出定性结论)
dsh-mementoApproval-gated cross-session memory: ctx.memory seam + SQLite + memory tool
dsh-nsfc-form-check国家自然科学基金申请书形式审查与匿名化提示(依据《国家自然科学基金条例》与申请人导入的当年指南,仅提示差异,不作出定性结论)
dsh-nurse-record-check护理记录时限、签名与评估表完整性校验(依据《病历书写基本规范》等公开文件,仅提示差异,不作出定性结论)
dsh-observeOpenTelemetry and Langfuse observability exporter for DeepSeek Harness.
dsh-origin-rvc-check原产地区域价值成分核对(按 RVC 定义式与门槛核对原产地判定自洽,仅提示差异,不作出定性结论)
dsh-ota-review-check在线点评回复台账核对(按回复时限、问题分类与整改状态核对台账闭环,仅提示差异,不作出定性结论)
dsh-output-stylesClaude Code outputStyles-equivalent runtime style switching
dsh-paper-doc-adapter试卷解析结构核对(按题型、答案、分值与 yotta 标识核对试卷结构自洽,仅提示差异,不作出定性结论)
dsh-permission-rulesClaude Code-style declarative allow/deny/ask permission rules with audit
dsh-permit-report-check行政许可办理核对(按申请材料、法定时限与决定记录核对台账闭环,仅提示差异,不作出定性结论)
dsh-pipeline-check项目全流程文件链条核对(按环节先后与金额口径核对链条自洽,仅提示差异,不作出定性结论)
dsh-pleading-draft起诉状要素齐备性核对(按诉请、事实、证据、法条四要素核对文书齐备,仅提示差异,不作出定性结论)
dsh-plugin-doctorZero-dependency static + sandbox smoke detector for DSH plugins
dsh-plugin-guidePlugin-development knowledge base as an on-demand agent skill
dsh-plugin-kitShared zero-runtime-dependency toolkit for the PerryLink DSH plugins
dsh-plugin-upgradeOne-package, one-corridor-index plugin upgrade skill: routes a repository to the matching closed corridor card
dsh-policy-brief-draft政策专报要素核对(按观点、依据、出处与建议核对专报齐备,仅提示差异,不作出定性结论)
dsh-power-loss-split线损电量拆分与考核表核对(依据公开的线损计算口径,仅提示差异,不作出定性结论)
dsh-power-ticket-check电力工作票要素齐备性与签发许可顺序核对(依据现行电力安全工作规程,仅提示差异,不作出定性结论)
dsh-ppap-checkPPAP 提交要素齐备性核对(按公开的 PPAP 手册与提交等级核对要素齐备与版本填写,仅提示差异,不作出定性结论)
dsh-protest-deadline质疑与投诉期限核对(按公开的政府采购质疑投诉规定核对期限与台账自洽,仅提示差异,不作出定性结论)
dsh-railway-window铁路施工天窗台账核对(按时间窗、时长算术与命令号核对台账自洽,仅提示差异,不作出定性结论)
dsh-reachMulti-channel approval/question bridge: WeChat/Telegram/Feishu, session console🧊 FROZEN — see the repo README
dsh-repair-order-qc维修工单结算核对(按项目金额、配件工时合计与结算总额核对算术自洽,仅提示差异,不作出定性结论)
dsh-research-reportVerifiable research-report engine: content-addressed evidence ledger and sealed versions
dsh-review-reply-check审稿意见逐条回应覆盖核对(按意见与回应一一对应核对覆盖完整性,仅提示差异,不作出定性结论)
dsh-rulefile-check规则库文件自检核对(按条款引用纪律与效力上限核对规则库自身合规,仅提示差异,不作出定性结论)
dsh-safety-brief-check安全技术交底记录要素齐备性与签字闭环核对(依据公开的安全生产法规与检查标准,仅提示差异,不作出定性结论)
dsh-scoreMulti-dimensional quality scoring for DeepSeek Harness plugins.
dsh-session-pinPin sessions in the Web sidebar with durable ordering🚫 RETIRED — see the repo README
dsh-session-syncCross-device session sync for DeepSeek Harness — a dedicated git mirror of your session store.
dsh-site-log-check监理日志跨日连续性与旁站覆盖提示(依据 GB/T 50319-2013 等公开文件,仅提示差异,不作出定性结论)
dsh-skill-pack-securitySecurity-audit skill pack: secret scan, dependency and supply-chain review
dsh-soe-decision-check三重一大决策台账核对(按前置研究、会议审议与决议记录核对程序留痕,仅提示差异,不作出定性结论)
dsh-soilwater-check土壤与地下水监测台账核对(按点位、监测项目、限值与超标判定核对台账自洽,仅提示差异,不作出定性结论)
dsh-sop-sync-check作业规程与 FMEA/控制计划一致性核对(按编号与版本核对三份文件是否同步,仅提示差异,不作出定性结论)
dsh-spc-gbt-adapter控制图常数与过程能力指数核对(按 GB/T 4091 的常规控制图常数表核对控制限与 Cp/Cpk 的自洽性,仅提示差异,不作出定性结论)
dsh-talkVoice-first session loop for DeepSeek Harness: talk to it, hear it answer.
dsh-team-roomsCross-session team rooms: shared message bus, task board and timeline🚫 RETIRED — see the repo README
dsh-tender-extract招标文件条款摘录核对(按出处与原文逐字核对摘录完整性,仅提示差异,不作出定性结论)
dsh-tender-matrix评标因素评分矩阵核对(按分值上限与合计核对矩阵自洽,仅提示差异,不作出定性结论)
dsh-test-driveIsolated install-and-smoke test drives for DeepSeek Harness plugins.
dsh-ticktickTickTick/Dida365 task bridge: session-header panel + 11 tools
dsh-translateVendor parameter translation and deterministic JSON repair for DeepSeek Harness.
dsh-warranty-calc质保期与索赔金额核对(按质保期月数与里程、索赔金额算式核对自洽,仅提示差异,不作出定性结论)

Install from the DSH Desktop Market

All PerryLink plugins are browsable in the built-in DSH Desktop Market: Market → Sources → add source → paste https://perrylink-dsh-catalog.perrylink.workers.dev/catalog-source.json → select it. Installation still goes through the Market's npm-identity verification and your confirmation.

License

Apache License 2.0 © 2026 dsh-auto-review contributors

Keywords

deepseek-harness

FAQs

Package last updated on 18 Oct 2026

Related posts