Skills Plugins MCP Prompt Model 导航 博客 资讯 我的中心
安全与权限 #cordis#deepseek-harness#dsh#plugin#privacy#redaction

dsh-redaction

Preventive content policy for DeepSeek Harness tool results: rewrite matched text with regex rules, or drop/truncate unpredictable payloads by field path before they are normalised, rendered, or persisted. The upstream counterpart to dsh-plugin-redact.

l-ingqin12 @l-ingqin12 ⬇ 1 ★ 0 main

安装

dsh plugin --profile web add github:l-ingqin12/dsh-redaction
下载安装清单

需要可复现安装时,可在仓库后追加 #commit 固定提交。

Preventive content policy for DeepSeek Harness tool results: rewrite matched text with regex rules, or drop/truncate unpredictable payloads by field path before they are normalised, rendered, or persisted. The upstream counterpart to dsh-plugin-redact.

该插件未提供要点说明,请参考仓库 README。

cordisdeepseek-harnessdshpluginprivacyredaction
  1. 安装并启动 DeepSeek Harness:npx @deepseek-ai/dsh web
  2. 在终端执行上面的安装命令(CLI 会解析插件并核验来源)
  3. 用 dsh plugins list 确认已安装,必要时重启 Harness 生效

插件以当前 dsh 进程的权限运行,安装时可能执行代码。请先通读仓库源码与许可证,确认无破坏性命令与越权访问;本站只做索引,不对第三方插件安全性作担保。

代码仓库github.com/l-ingqin12/dsh-redaction
许可证MIT
主要语言main
下载量1
GitHub 星标0
最近推送2026-09-12
收录日期2026-09-19
分类安全与权限

事实信息来自公开插件目录快照(2026-10-01),介绍文案由本站再加工。

以下为插件仓库 README 全文(原始内容,由公开目录抓取整理)。

# dsh-redaction

Two plugins for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness), plus the platform research that produced them.

The problem they solve: a public web search, a `gh` command, a log scrape — any tool can return content you must not keep. In DSH that content does not merely pass through: **the stored `tool/result` event *is* the model-facing message**, so one write commits it to both the durable session log and every future provider request. If it is the kind of thing a provider's content filter rejects, that turn fails — and so does every turn after it, because the history keeps carrying it.

## The two packages

| Package | Layer | What it does |
|---|---|---|
| [`dsh-plugin-content-policy`](packages/dsh-plugin-content-policy) | **prevention** | Rules and structural stripping applied on the `tools/execute` waterfall, before the result is persisted. Rewrites the result **`value`**, so the rendered text *and* the persisted `meta` are cleaned together. |
| [`dsh-plugin-redact`](packages/dsh-plugin-redact) | **remediation** | In-place redaction and rollback of existing `session.vN.jsonl.zstd` logs, driven from inside `dsh-tui`. Includes a frame-level engine (also usable as the `dsh-redact` CLI), a live in-session `hide`, turn rollback, and undo. |

They are deliberately separate: prevention cannot help with what is already on disk, and remediation does nothing about the next search result.

```powershell
dsh plugin --profile  add ./packages/dsh-plugin-content-policy
dsh plugin --profile  add ./packages/dsh-plugin-redact
dsh --profile  --dump-config     # confirm both rows composed
```

`/redact pick` — the keyboard-selectable node list — is **off by default**: the modal dialog can lock the TUI keyboard when an approval panel is pending. See [`docs/01-platform/dsh-tui-internals.md`](docs/01-platform/dsh-tui-internals.md) for the mechanism, and the package README for the one-line opt-in.

## The research behind it

Everything in [`docs/reports/`](docs/reports) was established by reading the installed deployment and running it — not from documentation, which does not cover most of it. These are the raw artifacts, kept because the conclusions are only as good as the evidence:

| Path | What it is |
|---|---|
| `reports/redteam/` | Adversarial review of the redaction tool: ten findings with mechanisms, repro scripts, and the reader-as-oracle verdicts. Two of them made a session permanently unopenable while the tool reported success. |
| `reports/fix/` | The fixes, with before/after output captured per finding, plus the suite results |
| `reports/dialog-root-cause/` | Why a plugin dialog can lock the terminal keyboard: the exact three-part mechanism, a deadlock-state matrix, and standalone repro scripts |
| `reports/dialog-contract/` | The real `tuiDialogs` contract — validation bounds, promise semantics, the one throw path, and whether a renderer can be detected before opening a modal (it cannot) |
| `reports/boot-verify/` | Reproductions of the real `boot()` path: load/activation sweeps, config-boundary matrices, the dual-track `Config` comparison, and the measurement that shows `--dump-config` **does not import plugin modules at all** |
| `reports/surveys-existing-plugins.zh.md` | What already existed in the DSH plugin ecosystem before this was written, and where each near-miss stops short |

A synthesized set of platform notes (session-log format, persistence internals, the tool-result pipeline, the TUI's extension surfaces, a defect catalogue and a process retrospective) lives in the author's local Obsidian vault rather than here, because it is written against that vault's linking and metadata conventions.

## Verification status

| Suite | Assertions |
|---|---|
| `dsh-plugin-redact` handler | 248 |
| `dsh-plugin-redact` regression (real reader as oracle) | 54 |
| `dsh-plugin-redact` hardening | 78 |
| `dsh-plugin-redact` engine / CLI | 34 |
| `dsh-plugin-content-policy` (4 suites) | 103 |

The `dsh-plugin-redact` engine is additionally validated by opening its output with the **real** `JsonlSessionPersistence.open()`; a suite that only exercises the tool's own self-check is not accepted as evidence (that mistake shipped a defect — see the retrospective).

Requires **Node >= 22.15** for the zlib zstd API. The plugins themselves have no runtime dependencies — only optional peers.

### Reproducing these checks locally

```bash
cd packages/dsh-plugin-redact        && npm test   # engine 34 + handler 248 + torn-tail 11 + CLI smoke
cd packages/dsh-plugin-content-policy && npm test  # the two pure suites: 45 + 36
node .github/scripts/portability.selftest.mjs      # from the repo root
node .github/scripts/pack-check.mjs                # from the repo root
```

`.github/workflows/ci.yml` runs those same commands on `ubuntu-latest` and `windows-latest` across Node `22.15`, `22.x` and `24.x`. The suites that need a real DSH install are deliberately **not** in CI: they derive the install location from `DSH_HOME` and exit `3` when it is missing, rather than passing vacuously.

If you develop on Windows you can reproduce the Linux leg before pushing, instead of waiting for a red build. WSL is enough — no Docker needed:

```bash
curl -fsSL https://nodejs.org/dist/v22.21.0/node-v22.21.0-linux-x64.tar.xz | tar -xJ -C /opt
/opt/node-v22.21.0-linux-x64/bin/node test/engine.selftest.mjs
```

#### Why there is a portability guard

The first CI run failed after 37 s: `test/preflight.mjs` read `process.env.USERPROFILE`, which is `undefined` on Linux, so `path.join(undefined, '.dsh')` threw `ERR_INVALID_ARG_TYPE`. That file is in the npm `files` allowlist, so **every non-Windows consumer running `npm test` would have hit it**. A test run on Windows alone cannot see this class of bug — it is invisible precisely where it is written.

`.github/scripts/portability.mjs` therefore statically scans the shipped code and tests of both packages for four Windows-only assumptions:

| Rule | What it catches |
|---|---|
| `win-only-env` | `USERPROFILE` / `HOMEDRIVE` / `APPDATA` / `LOCALAPPDATA` used without an immediately following `??` or `\|\|` fallback |
| `import-meta-pathname` | `import.meta.url` combined with `.pathname`, which leaves `%20` in paths containing spaces |
| `hardcoded-win-path` | A hard-coded drive letter in a string literal |
| `path-win32` | `path.win32`, which forces Windows semantics on every platform |

The rule for `win-only-env` is deliberately about *the variable*, not the line: `DSH_HOME ?? path.join(process.env.USERPROFILE, '.dsh')` contains a `??` and is still broken.

Its self-test is the point of it. `portability.selftest.mjs` **injects the real `USERPROFILE` defect back into `preflight.mjs`**, asserts that the guard fails and names both the file and the correct line, then restores the file in a `finally`. A guard that cannot fail is worse than no guard, and a line number hard-coded into the test is a guard that goes red for the wrong reason.

#### Why there is a pack check

The `files` allowlist in each `package.json` is maintained by hand, and `index.js` imports `lib/engine.mjs` while `bin/dsh-redact.mjs` imports it a second time. Add an import and forget the allowlist entry, and every check here stays green while the published package is missing a file — a failure that only the consumer can see.

`.github/scripts/pack-check.mjs` asks npm what it would actually publish (`npm pack --dry-run --json`), then walks every relative import inside the shipped entry points and requires each resolved target to be in that tarball. It also asserts that nothing from a test run (`fixture.*`, `plan-*.json`, `needle.txt`, `broken.zstd`) rides along. Removing `lib/engine.mjs` from the allowlist makes it report both importers by name.

## License

MIT — see [`LICENSE`](LICENSE).

Maintainers: [`PUBLISHING.md`](PUBLISHING.md) covers the npm release steps and the pre-publish gates.

数据来源:公开的 DeepSeek Harness 插件目录与各插件 GitHub 仓库。本站为独立第三方目录,与 DeepSeek、幻方(High-Flyer)及插件作者均无隶属或背书关系。

每日精选 Skill 推荐,免费送到你邮箱

输入邮箱,每天接收一个精选 AI Agent 技能推荐。完全免费,持续更新。

提交后我们会发送一封确认邮件,点击邮件里的链接才会开始收信。

完全免费,取消任意时间。我们不会发送垃圾邮件。