@jayyuen66/dsh-danger-guard
Pre-execution guard: a `tools.guard` predicate decides allow, ask or refuse per permission preset for dangerous shell commands (git hook bypass, catastrophic `rm`, download-and-run, git history rewrites) and for edits to credential paths or to files the turn never read, and hands the model the reaso
Install
dsh plugin --profile web add @jayyuen66/dsh-danger-guard
Sandbox test
This plugin has not been tested yet. Submit a test →
README
<p align="center">
<img src="https://cdn.jsdelivr.net/gh/JayYuen666/dsh-danger-guard@main/icon.svg" width="96" height="96" alt="dsh-danger-guard logo" />
</p>
<h1 align="center">dsh-danger-guard</h1>
<p align="center"><em>Dangerous shell commands and credential edits, physically refused before dispatch.</em></p>
<p align="center">
<a href="https://www.npmjs.com/package/@jayyuen66/dsh-danger-guard"><img src="https://img.shields.io/npm/v/@jayyuen66/dsh-danger-guard?style=flat-square&logo=npm&logoColor=white" alt="npm version" /></a>
<a href="https://www.npmjs.com/package/@jayyuen66/dsh-danger-guard"><img src="https://img.shields.io/npm/d18m/@jayyuen66/dsh-danger-guard?style=flat-square" alt="npm downloads (18 months)" /></a>
<a href="https://github.com/JayYuen666/dsh-danger-guard/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/JayYuen666/dsh-danger-guard/ci.yml?branch=main&style=flat-square&label=ci" alt="ci" /></a>
<img src="https://img.shields.io/badge/license-MIT-4c1?style=flat-square" alt="MIT" />
<img src="https://img.shields.io/badge/node-%3E%3D24.9-4c1?style=flat-square&logo=nodedotjs&logoColor=white" alt="node" />
<img src="https://img.shields.io/badge/dsh-%5E0.2.1--rc.5-658EFF?style=flat-square" alt="dsh" />
<a href="https://github.com/deepseek-ai/deepseek-harness"><img src="https://img.shields.io/badge/powered_by_dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white" alt="powered by dsh" /></a>
</p>
<p align="center">
<img src="https://skillicons.dev/icons?i=typescript,nodejs,react,vitest,githubactions" alt="tech stack" />
</p>
<p align="center">
<a href="https://github.com/JayYuen666"><img src="https://img.shields.io/badge/GitHub-JayYuen666-181717?style=flat-square&logo=github&logoColor=white" alt="GitHub" /></a>
<a href="mailto:cqwkkj@gmail.com"><img src="https://img.shields.io/badge/Email-cqwkkj@gmail.com-EA4335?style=flat-square&logo=gmail&logoColor=white" alt="Email" /></a>
<a href="https://twitter.com/JayYuen666"><img src="https://img.shields.io/badge/Twitter-X%2FJayYuen666-000000?style=flat-square&logo=x&logoColor=white" alt="Twitter/X" /></a>
<a href="./README.zh-CN.md"><img src="https://img.shields.io/badge/lang-简体中文-658EFF?style=flat-square" alt="简体中文" /></a>
</p>
A pre-execution guard for dsh: dangerous shell commands and credential edits are physically refused before dispatch, and the model is handed the reason plus a working way out.
<img src="https://api.iconify.design/lucide/file-text.svg?color=%23658EFF&height=22" height="22" width="22" align="absmiddle" alt="" /> Contents
- [What it does](#what-it-does)
- [Install](#install)
- [Verify it is live](#verify-it-is-live)
- [What it does not provide](#what-it-does-not-provide)
- [Enabling it in dsh](#enabling-it-in-dsh)
- [What the rules block](#what-the-rules-block)
- [Settings](#settings)
- [What each permission preset blocks](#what-each-permission-preset-blocks)
- [Known boundaries](#known-boundaries)
- [Data and privacy](#data-and-privacy)
- [FAQ](#faq)
- [Development](#development)
- [License](#license)
<img src="https://api.iconify.design/lucide/shield.svg?color=%23658EFF&height=22" height="22" width="22" align="absmiddle" alt="" /> What it does
- It blocks, it does not advise. The decision lives in the synchronous predicate on
ctx.tools.guard: returning a string rejects that call. The host turns the reason into the call's error result, so the model reads "why this was refused, and what to write instead" - not a silent failure. - Three defences:
- Dangerous
bash/pwshcommands (bashVerdictOfinlib/danger-rules.ts): git hook bypass, catastrophicrm, download-and-run, long-running dev servers, the git destruction family, and the infrastructure destruction family. - Credential and secret paths on edit/write/apply_patch tools (
secretPathDeny) - matched by argument key shape for single-target editors, and by the official patch parser forapply_patch, never by tool name, because tool names drift with the provider. - The editor path face has a second refusal key,
opaqueTarget: a target longer than the judgable length limit is neither confirmed nor cleared as a credential, so it is denied with a "paste the path to the user, do not retry verbatim" message. Same principle asnestedShellUnconfirmedon the bash side - cannot judge is not the same as safe. (An over-long command resolves tonestedShellUnconfirmedinstead.) - The first-edit fact gate (
lib/fact-gate.ts): an edit that has not read its target, or that touches a risky surface without layer evidence, gets refused with the missing evidence attached.apply_patchis judged per operation target (a move counts both its source and its destination); an empty patch, one the official parser rejects, or one overAPPLY_PATCH_TARGET_LIMIT(128) is refused outright instead of partially applied, and that refusal does not depend onfactGateEnabled. - "Has read" counts successful calls only: the evidence ledger joins
tool/calltotool/resultbycallId, and a call without one has unknown status and does not count (the host appends the call before dispatching, so a call that never ran or already failed looks exactly like a successful one in the log). - "Which revision was read" lives in
lib/read-basis.ts: the observation baseline and the staleness point are one record, and it is committed only after a successful result - a failed or blocked read cannot advance the baseline and thereby swallow an external change. Once an external change is attributed it stays in force until a successful read actually lands (or the preflight hands the body over in a deny reason). - Preflight gathers that evidence itself (two faces on two waterfalls, split by when evidence actually becomes visible):
- Face A, on
tools/post-execute: a read-only inspection (`rea
…(truncated)
Rendered from the README published on npm. Formatted only, not edited.
Versions
Published on npm::17,最后更新 2026-11-05