插件目录 / Developer / dsh-smart-approval
dsh-smart-approval
未验证 TingRuDeng
功能简介
Fail-closed three-mode approval plugin for DeepSeek Harness
未验证 — 尚未实测
Fail-closed three-mode approval plugin for DeepSeek Harness 尚未验证——请自行安装测试。
「未验证」表示我们的自动化 CI 尚未安装过该插件。功能描述与版本兼容性均为作者声明。这不是安全审计,也不代表对第三方代码的背书。
README
dsh-smart-approval
dsh-smart-approval is a fail-closed approval plugin for
DeepSeek Harness. It separates
access permission from automatic review: DSH continues to own Read Only,
Workspace Write, and Full access, while this plugin adds an independent review
selector beside Workspace Write.
New sessions use smart approval by default. Changing review mode does not change
the sandbox, and changing access permission does not change review mode. Both
changes apply to the next approval request without restarting DSH.
[!WARNING]
This project and DSH are both in developer preview. Review the security
boundaries below and pin exact versions in reproducible environments.
Two independent selectors
The Web composer should show two controls:
[ Workspace Write ▾ ] [ Smart approval ▾ ]
- Access: Read Only, Workspace Write, and Full access, owned by DSH.
- Automatic review: Manual approval, Smart approval, and Unattended, owned by
this plugin.
| Review mode | Safe request | High-risk or uncertain | Clearly malicious |
|---|---|---|---|
| Manual approval | Ask a human | Ask a human | Ask a human |
| Smart approval (recommended default) | Allow once | Ask a human | Reject |
| Unattended | Allow once | Reject | Reject |
Automatic review only handles requests that already enter DSH'sapproval/request waterfall. It never expands the current access permission or
switches a session to Full access.
Install
Requirements
- Node.js 24 or later.
- DeepSeek Harness
>=0.1.1-rc.1 <0.2.0(current verification baseline:0.1.1-rc.2). pnpmonPATH; DSH forwards plugin-management operations to pnpm.
After installing the DSH CLI globally:
npm install --global @deepseek-ai/[email protected]
dsh plugin --profile web add [email protected]
dsh --profile web --dump-config
dsh web
For one-off execution:
npx @deepseek-ai/[email protected] plugin --profile web add [email protected]
npx @deepseek-ai/[email protected] --profile web --dump-config
npx @deepseek-ai/[email protected] web
npm dsh ... is not a valid npm command. Use dsh ... after a global install,npx @deepseek-ai/dsh ... for one-off execution, or pnpm dsh ... from a
DeepSeek Harness source checkout.
DSH accepts an exact plugin version. After the stable release is published, the
following form is supported:
dsh plugin --profile web add [email protected]
Install from a checkout or GitHub
From this repository:
dsh plugin --profile web add .
From a DeepSeek Harness source checkout:
pnpm dsh plugin --profile web add /absolute/path/to/dsh-smart-approval
pnpm dsh --profile web --dump-config
pnpm dsh --profile web
Pin a reviewed GitHub commit:
dsh plugin --profile web add github:TingRuDeng/dsh-smart-approval#<commit-sha>
Git dependencies run this package's prepare build. pnpm 10 and later block
dependency build scripts by default. On first Git install, follow DSH's prompt
to add the exact package name to that profile's pnpm-workspace.yamlallowBuilds, review the source, and retry. Registry packages already include
built output and do not need that permission.
Verify or remove
dsh --profile web --dump-config
The result should contain the dsh-smart-approval bundle and smart-approval
plugin row. The permission configuration should still contain only DSH's native
Read Only, Workspace Write, and Full access choices. After Web starts, the
automatic-review selector should appear separately beside access permission.
Remove the plugin with:
dsh plugin --profile web remove dsh-smart-approval
Use and switch modes
Use the independent automatic-review selector in Web, or run one of these in
the current session:
/approval-mode manual
/approval-mode smart
/approval-mode unattended
/approval-mode without an argument returns the current mode. Access permission
continues to use DSH's native /permission command; the two command families do
not rewrite each other's state.
/approval-log lists this session's automatic decisions (the latest 10 by
default, or /approval-log 30 for the latest 30). Each line shows only the
time, tool, outcome, reason code, and review mode; arguments and model output
are never included. Set decisionLogSize: 0 to disable the audit.
Sessions without an explicit selection use defaultMode, which defaults tosmart. Explicit selections are stored as a Session-bound storage-domain
sidecar; an unselected session continues to follow the configured default so
the host decision and browser projection stay aligned after configuration
changes. The plugin never appends a non-portable event to the Session log.
During an upgrade from an earlier preview, legacy smart-approval/mode events
are read only for one-way sidecar migration; older smart-approval andunattended permission presets migrate to smart and unattended. Migration
does not modify permission events.
How it works
The plugin is an early answerer in DSH's approval/request waterfall:
- It resolves the real
tool/callevent bycallId. DSHbash,pwsh,write, andedithave closed, versioned action adapters. Unknown tools or
future argument fields fail closed. - It combines the current turn with bounded recent direct-user text. Newer
constraints override older scope, and the payload says when older history
was omitted. Assistant messages, tool output, model-written justifications,
and earlier approval outcomes never establish authority. - It sends only execution semantics. Shell review receives the command and
execution fields;writereceives the exact path and complete new content;editreceives the exact path, old/new strings, and replace-all flag.
Model-authored descriptions and justifications are removed. - File mutations use DSH's filesystem service for read-only evidence: resolved
display path, workspace containment, path/target type, and optional byte
size. File content is not read. Final symlinks, canonical path aliases,
malformed metadata, sensitive paths, and protected system locations stop
before model review. - Deterministic checks also stop credential material, destructive commands,
system changes, background work, dependency installation, publishing,
remote writes, uploads, and sensitive workspace/workdir conditions. - The model returns a strict four-field classification:
riskLevel,authorization,intent, and a closedreasonCode. It cannot directly
grant permission. Local code allows only low-risk benign work with high or
medium direct-user authorization; uncertainty is handed off and clearly
malicious intent is rejected according to the selected mode. - Every successful classification becomes only
allowed-once. The next
similar request is inspected and classified again. Timeouts, exceptions,
malformed output, incomplete evidence, cancellation, or a mode change fail
closed under the active mode.
Repeated requests are re-reviewed, not remembered
If the user asks for several ordinary writes and each exact request is clearly
within that intent, smart approval can allow the second and later requests
without another click. Each request still makes its own model call and receives
its own one-shot grant. A previous human click or model result never creates a
directory allowlist, cached precedent, or permanent permission.
Configuration
The current session route performs review by default. To use an independent
route, override the plugin row in the profile's cordis.patch.yml:
- id: smart-approval
config:
defaultMode: smart
reviewerProvider: your-provider-route
reviewerModel: your-model-id
timeoutMs: 15000
maxTokens: 128
reviewerProvider and reviewerModel must be configured together.
| Field | Default | Purpose |
|---|---|---|
defaultMode |
smart |
New-session mode: manual, smart, or unattended |
reviewerProvider / reviewerModel |
Current session route | Optional independent reviewer route; configure as a pair |
timeoutMs |
15000 |
Hard deadline for the complete review call |
maxTokens |
128 |
Maximum reviewer output |
maxToolArgumentChars |
12000 |
Tool-argument limit; overflow fails closed without truncation |
maxUserMessages |
4 |
Current plus recent direct-user message limit; older history is omitted explicitly |
maxUserContextChars |
8000 |
User-context limit; the current turn is never truncated, while older history may be omitted explicitly |
decisionLogSize |
50 |
Decision-audit entries kept per Session lifecycle; 0 disables the audit entirely |
The bundle does not override the permission row, so it does not replace a
profile's existing permission presets.
Model, data, and security boundaries
- Manual mode invokes no reviewer. Smart and unattended modes send the
workspace root, normalized action, bounded recent direct-user text, and
content-free file-target metadata to the review provider. Forwriteandedit, the normalized action includes the exact new/replacement text needed
to classify the mutation; detected credential material is stopped locally.
The model classifies risk, authorization, and intent from that bounded
history. Deterministic local prechecks run before the model, and a closed
local mapping turns the strict classification into the final mode-specific
decision; older text is therefore context, not a persistent grant. - Reusing the current session model is convenient but is not an independent
security review. Sensitive deployments should use a separate controlled
provider route. - Only requests that already enter DSH's approval channel can be reviewed.
Network or remote actions that do not trigger approval are outside this
plugin's control. - Model classification is not a security proof. Unknown tools or arguments,
filesystem aliases, background execution, and non-text or incomplete context
fail closed: smart mode asks a human and unattended mode rejects. - Every automatic approval is one-time and every repeated request is reviewed
again. The plugin stores no decision cache, directory allowlist, approval
precedent, or permanent grant. - Logs contain tool name, outcome, and short reason code, not full prompts,
arguments, credentials, or model reasoning. - The persistent decision audit (
/approval-log) stores only the time, tool
name, outcome, reason code, review mode, and tool-call id per decision. It
never stores arguments, prompts, user text, or model output, and it is
disabled bydecisionLogSize: 0. Audit writes are a side channel: a failed
audit write never changes the approval outcome. - Smart fallback and manual mode require another Web, ACP, or custom human
answerer. Without one, DSH remains fail-closed. - File-target inspection happens before approval and execution, so a path can
theoretically be replaced in between (TOCTOU). Underworkspace-write, DSH
normalizes and checks the target again before the mutation, which narrows but
does not eliminate that race. A one-timedanger-full-accessapproval has
broad filesystem authority and does not provide the same containment check.
This plugin cannot fully remove path-replacement races without atomic
no-follow/open-relative primitives in DSH core; keep untrusted processes out
of the workspace while an approval is pending. - DSH currently has one
workspace-writeroot. A one-time Full access approval
still has broad filesystem authority; this plugin does not turn it into a
multi-root sandbox.
Repository map for maintainers and agents
| Path | Responsibility |
|---|---|
src/index.ts |
Service injection, legacy migration, projection, command, and lifecycle |
src/review-mode.ts |
Legacy-event migration, command lifecycle fold, and browser projection |
src/review-mode-storage.ts |
Session-lifecycle-bound review-mode sidecar and decision-audit table |
src/client/ |
Web selector and browser-plugin registration |
src/approval-handler.ts |
Three-mode routing, waterfall decisions, and post-review mode recheck |
src/review-context.ts |
Closed action adapters and bounded direct-user context extraction |
src/file-target-inspector.ts |
Read-only DSH filesystem evidence and path safety classification |
src/review-policy.ts |
Deterministic prechecks, strict classification parser, and local decision mapping |
src/llm-reviewer.ts |
Reviewer prompt, stream parser, strict assessment protocol, and timeout |
cordis.patch.yml |
Host-plugin mount only; it does not override permission presets |
tests/ |
Host, policy, protocol, migration, projection, and browser contracts |
Invariants: permission and review mode never rewrite each other; missing or
ambiguous evidence never becomes an automatic allow; only bounded direct-user
text can establish authority and newer constraints win; previous approvals are
never authorization; only a locally mapped low-risk benign assessment returnsallowed-once; manual mode inspects no request content and calls no model; and
a mode change during inspection or review invalidates the original result.
Development
pnpm install
pnpm test
pnpm run typecheck
pnpm run build
pnpm pack --dry-run
The supported DSH range is >=0.1.1-rc.1 <0.2.0; the current verification
baseline is 0.1.1-rc.2. Real-provider end-to-end
review and human-fallback interaction still require deployment credentials and
environment-specific acceptance testing.
License
安装
装一次目录插件,之后本站所有插件都能让 DeepSeek Harness 自动找、自动装:
dsh plugin add dshbase-catalog 然后对 agent 说「帮我装 dsh-smart-approval」,它会在目录里找到并自动安装。文档:dshbase-catalog · 已验证场景包。
该插件是 GitHub 源码(未发 npm)——直接从仓库装:
Web profile:
dsh plugin --profile web add github:TingRuDeng/dsh-smart-approval Headless(CLI)profile:
dsh plugin --profile headless add github:TingRuDeng/dsh-smart-approval 实测报告
尚未 L3 验证——若已跑过,见下方失败备注。