DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

Threat Gate — DSH Plugin for DeepSeek Harness
DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins

@cyd-prc/dsh-threat-gate

Threat Gate

Session-level threat scoring for the DeepSeek Harness: a port of the EntropyRuntime session threat tracker (PATCH-02) — sliding-window signal accumulation, three scoring rules, three levels — measuring and recording only by default, with an optional criti

The plugin will be installed here. Keep web if you are unsure.

npx -y @deepseek-ai/dsh plugin --profile web add @cyd-prc/dsh-threat-gate@0.2.4
READMECompatibilityVersions

Compatibility and provenance

Threat Gate is published as @cyd-prc/dsh-threat-gate and currently resolves to version 0.2.4. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
any
Release source
npm
Registry updated
10/16/2026

Versions

0.2.4stable
10/8/2026
0.2.3stable
10/8/2026
0.2.2stable
10/8/2026
Show 8 more versionsCollapse versions
0.2.1stable
10/7/2026
0.2.0stable
10/7/2026
0.1.7stable
10/6/2026
0.1.6stable
10/6/2026
0.1.5stable
10/4/2026
0.1.4stable
10/4/2026
0.1.3stable
10/3/2026
0.1.1stable
10/3/2026

Related plugins

Loading related plugins…

Latest
0.2.4
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
268.9 kB
Files
34
Surface
any
License
MIT
Source
npm
GitHub
★ 0
Weekly downloads
866
Security scan
✓ v0.2.4 scan passed
View source ↗Project homepage ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

Claim this Plugin →
Report an issue

Related plugins

More verified plugins in security-access.

Experimental Auto Review@deepseek-ai/dsh-experimental-auto-reviewPer-tool LLM authorization review for the DeepSeek Harness Auto permission presetCc Safety Netcc-safety-netA coding agent CLI hook - block destructive commands and secret file accessDoctor@linxin666/dsh-doctorTransactional rescue mode for DSH profiles with a supervised launcher, isolated recovery capsule, deterministic repairs, health monitoring, and a local Web recovery consolePocketdsh-pocketPut DeepSeek Harness in your pocket: one package, one settings page, and scan a QR code on your phone to access DSH on your computer in sync (LAN + public network, real-time screen mirroring).

README

dsh-threat-gate

Session-level threat scoring for the DeepSeek Harness — a faithful port of the EntropyRuntime session threat tracker (PATCH-02, audit/threat_tracker.py).

Measures and records by default; vetoes only when you tell it to.

This plugin is the session plane, orthogonal to entropy-guard (control plane: can this tool be called at all) and shape-guard (content plane: what does relayed content carry). It watches the trajectory of a session — a sliding window of recent tool calls — and folds it into a 0–1 threat score with three levels: normal / suspicious / critical.

Scoring rules (weights and thresholds ported value-for-value)

RuleShapeWeight
A. Dense repeatsone signal ≥3 times in the window+0.1 × (count − 2)
B. Recon→exec ordera reconnaissance-family tool followed by an execution-family tool in the window+0.3
C. Rapid denials≥2 calls actually refused by a guard in the window+0.2 × count

Levels: critical ≥ 0.70, suspicious ≥ 0.40.

Two semantic corrections in 0.1.1, both found by an independent build-side audit (see the defect ledger below): ① "Execution family" means running code (bash/pwsh/run_code/shell/ execute/node/python), not write/edit. Including file writes made the ordinary coding loop — read a bit, then edit — score +0.3 every time, so read×3→write read as suspicious. ② Rule C counts only genuine refusals, never bare isError. Routine failures (network, missing path, disk full) are not escalations; counting them meant two failed writes reached critical, and a session at critical with vetoOnCritical is locked out. The full item-by-item port comparison is in DEVIATIONS.md.

What the level means (semantics, ruled in 0.1.7)

The level names a trajectory shape, not a danger verdict. Measured on a real, entirely benign plugin-development session (245 tool calls replayed against the published artifact): 90% of the time above normal, 40% at critical (FINDING-F1 plus the distribution follow-up). The rule shapes — dense repetition, recon-then-exec — are also the shape of ordinary coding; they do not separate intent.

Consequences:

  • vetoOnCritical is not recommended. With 40% of benign work at critical, enabling it turns an emergency brake into a random speed bump: write/edit/ pwsh refused four times in ten, and the session crawls along the read-only escape path (T1). If you need a veto, that lives on the control face (entropy-guard's utility gate, which governs targets and gears).
  • Do not read critical as "danger". It is a measurement of trajectory shape, recorded in the chain — it neither confirms nor rules out hostile intent.
  • Rule C's object, measured (MP-2026-10-13-01). rapidDenied reads the guard's return string: the tracker picks it up at index.js L67 via error.message ?? error.info.reason, and the guard's own wording is confirmed to match the pattern (measured by driving a real EntropyController.guard() at G0) — while which of the two fields carries it in the live host is not separately measured (the ?? chain reads both, so the conclusion holds either way). The chain's own call_rejected.reason carries the short form and does not match; testing the pattern against the chain string was an object-substitution error, caught and retracted. Suite anchors: the pattern answers the return string, the short form provably does not match, three worded refusals reach critical, and without the wording the component stays zero.
  • A critical level decays on its own as the window slides (measured: 0.8 → 0.6 → 0.3 with no intervention) — it is not a terminal state and needs no reset.

Install

npm install @cyd-prc/dsh-threat-gate

The bundle patch (cordis.patch.yml) inserts the row; every config field is optional. Default posture: measure and record only — set vetoOnCritical: true to have the gate monotonically deny side-effecting calls while a session is at critical.

ConfigDefaultNotes
windowSize10Counting window. An invalid value throws (0.1.1); it no longer falls back silently
vetoOnCriticalfalseWhen true, denies side-effecting calls at critical. Read-only tools stay available — a critical session keeps a read-only escape path
readOnlyPatternread-only verbsWhat counts as read-only (0.1.2). Covers verb-first (read, grep, glob), verb-last (job_list), and *_status/*_state/*_info. Anything unmatched is treated as side-effecting (fail-closed). Network tools are deliberately not exempt — web_fetch/web_search read outward, and cutting egress is the point of a lockdown
denyPatternguard refusal wordingThe "genuinely refused" test; override to match another refusal source

Surface

  • Tool — threat_status (read-only, exempt from the gate): score, level, rule breakdown, window, level-change count.
  • Command — /threat → status (default) | reset.
  • Audit chain — same chain as entropy-guard / shape-guard ($DSH_HOME/entropy-guard/<agent>.jsonl), threat_level events carry {from, to, score, window, rules} — so one export answers "what the session did and how dangerous its trajectory looked".

Upgrade path (reserved)

shape-guard chain entries carry a threat_score_hint field that is deliberately null today ("an unmeasured correlation is not a measurement"). Threat-gate's score is the future value of that field: when both plugins are installed, the shape face can tighten policy as the session score rises. This version only measures and records — the coupling is intentionally one-directional until the test side signs it.

Defect / change ledger

0.2.4

  • The veto anchor is pinned. When vetoOnCritical is on, report() must still name the read-only escape path (read-only tools stay available); when off, it must name the recommended posture (measure & record only). Three places declare the veto's semantics (config comment, report line, README semantics section) — the anchor keeps them from drifting apart, which is the failure mode where a wording edit in one place orphans the T1 escape path.
  • Measurement-basis correction (0.2.2's heap number). The 0.2.2 note said "+6.8 MB heap" for a 10k-line harvest; that measured heapUsed at harvest end. A second measurement holding the full 10k-entry result resident reads +15.6 MB. Both are real; they count different things (transient working set vs retained result). Stated so the numbers stop pretending to be one number.

0.2.3

  • What rule C observes, pinned (MP-2026-10-13-01). The suite now anchors the denial-wording object: the pattern answers the guard's return string, the chain's short form provably does not match, three worded refusals reach critical, and without the wording the component stays zero. Plus tools/check-denial-wording.mjs, a workspace-only probe driving a real EntropyController at G0 (SKIPs cleanly inside the artifact). No runtime change.

0.2.2

  • The baseline now survives restarts (ticket 2: history harvested from the chain). At controller creation, the session's recorded history is replayed into the baseline (baseline.fromChain: true, default) — measured on the live profile: after a restart the deviation read warming (0/20) while the chain already held 190 samples; now activation reads ready with baseline: chain. Named sources, never merged silently (acceptance anchor A/C): the reading carries baseline.origin ∈ {live, chain, merged}, and the report prints it. warming is never masked (anchor B): the live sub-state (live.state/live.samples) keeps reporting warming until this process has earned its own baseline — an unknown is never presented as a settled reading. The kill switch baseline.fromChain: false restores the 0.2.0 live-only behavior (no default change without a way back). Replaying the same chain twice is byte-identical (anchor D, pinned). Measured cost: harvest 1k lines ≈ 20 ms, 10k lines ≈ 87 ms (+6.8 MB heap) — roughly linear; per agent, once per process. Threat-model boundary stands: the baseline is the session's recorded normal, and init epochs mark process boundaries the live side has no concept of — the merged baseline knowingly spans them.

0.2.1

  • tools/replay-chain.mjs: replay a session from its chain and diff it against the live-recorded transitions — the instrument that closes FINDING-F1's open cell (pre-dispatch gate_decision order vs post-execution tools/result order). On the real session chain: 24/24 transitions match, bit-identical including every IEEE-754 tail. Two replay disciplines, both pinned by anchors: gate-denied decisions are skipped (they never executed, so the live stream never saw them — rule C in replay is always 0, declared not hidden), and an init entry restarts the window (process epochs: the live tracker's state is per-process — the one initial mismatch on the real chain was exactly a restart boundary, measured at seq 376/392). Read-only by construction; exit 1 on any mismatch.

0.2.0

  • Deviation-from-self (semantics-3): the reading now also compares the window to the session's own baseline. The absolute-threshold levels stay (compat; re-named in 0.1.7 as trajectory shape), and beside them each window is measured against the session's own history: the three rule components (unchanged — no new judges) get per-component quantiles (p50/p90) over the session's past readings, and aboveP90 marks a rhythm shift — a burst, a new tool family, an egress pattern. The promise, pinned by anchors: the steady benign rhythm that reached critical against absolute thresholds (FINDING-F1) is not a deviation from itself; a varied prefix followed by an execution burst is. Threat-model boundary, stated rather than hidden: a self-baseline catches rhythm changes; an attack that perfectly continues the session's own rhythm reads as normal — the price of a baseline with no labels. Deviation is measurement only and never feeds vetoOnCritical (still not recommended). threat_level chain entries carry deviation beside rules (additive; readers recompute from bytes either way). The baseline excludes the current window from its own history, so a shift is compared against what the session did before it — never diluted by the shift itself. Warmup: warming until 20 past-window readings exist.

0.1.7

#What was observedWhat the fix is
12The level was readable as "danger" while measuring trajectory shape. On a real benign dev session the published artifact sits above normal 90% of the time and at critical 40% (FINDING-F1 + the 245-call replay) — the rule shapes are the shape of ordinary coding, so the dynamic range was spent on benign workSemantics ruling (documented, not re-engineered): the level is a measurement, critical ≠ danger, vetoOnCritical is explicitly not recommended (an emergency brake that fires 40% of the time is a random speed bump), and report() says so. A baseline-deviation reading (per-session-type) is registered as the follow-up direction, not built here

0.1.6

#What was observedWhat the fix is
11D-1: the chain CLI crashed on every fresh chain. verify-chain.mjs read reading.sealed.count while the grader returns sealed: null for a never-sealed chain — the default state of every new chain killed the tool. No CLI-level test existed to catch itThe print path guards the null; the suite now carries its first CLI-level case (a fresh chain must exit 0 with VERIFIED). Found by the interim verifier (VR-2026-10-04-01)

0.1.5

#What was observedWhat the fix is
10The vendored ledger is now a real dependency. The byte-identical copy of shape-guard's lib/ledger.js (the V1 family: one fix landed in one package and not the other, twice) is retired; lib/ledger.js is a pure re-export of @cyd-prc/dsh-audit-chain, bundled with an exact pin so the installed artifact stays self-contained, and the release check verifies the bundled copy matches the pinlib/VENDORED.md retired into a historical note; the re-sync rule is now npm install's job. The shared contract's clause 8 and every earlier grading fix arrive with the dependency, and cannot drift again. Packaging note: bundleDependencies needs npm for packing — pnpm refuses bundled deps under its default isolated linker (ERR_PNPM_BUNDLED_DEPENDENCIES_WITHOUT_HOISTED); pnpm users reproducing a pack need nodeLinker: hoisted.

0.1.4

#What was observedWhat the fix is
9Vendored ledger re-synced to shape-guard 0.1.6 (S4 / contract clause 8). The 0.1.5 copy graded a torn tail line (a crash mid-append) tampered on its own — an availability event in the hostile grade — and its writer could fuse a new entry into the torn line, losing itWhole-file re-copy per the VENDORED.md rule (sha256 3A547663…, byte-identical to the source): corrupt is reported, never graded on its own, and the writer terminates a torn tail before appending. The provenance table also back-fills the 0.1.5 row it missed. The structural fix (a shared dsh-audit-chain package) stays open

0.1.2

#What was observedWhat the fix is
6vetoOnCritical denied everything, read-only tools included (T1, measured by the test side): at critical even read/grep were refused, so the session had no read-only escape path — it could only wait for a human to run /threat reset. Three places (the patch comment, lib/config.js, report()) said "side-effecting calls", so the docs and the implementation disagreedAdded readOnlyPattern: read-only tools are always allowed at critical (precedent: entropy-guard keeps G0 available while suspended — the paper's Theorem 4 recovery path). All three descriptions now say "side-effecting" and name the exemption. Anything unmatched counts as side-effecting (fail-closed). Anchors: the three T1 cases plus tools/live-check.mjs
7Is a network tool read-only? While widening the pattern, web_search was briefly exemptedDeliberately not exempt. web_fetch / web_search only "read", but they read outward; allowing them at critical leaves an egress path. This makes the plugin stricter than entropy-guard's G0 here, and that choice is pinned as an anchor (T1 设计判断)
8Neither verification tool shipped (T2): files had no tools/, so the community could recompute neither the chain reading nor the release checkShipped tools/verify-release.mjs (package-agnostic), tools/verify-chain.mjs (driving this package's lib/ledger.js), and tools/live-check.mjs — the last one is T1's instrument: the Node suite cannot reach the guard closure, which is exactly why the doc/implementation mismatch got out
—Vendored-ledger drift (V1), still open. lib/ledger.js is byte-identical to shape-guard 0.1.4, so a grading defect present there is present here too: one chain, three writers, two grader copies, one defect. The structural fix (a shared @cyd-prc/dsh-audit-chain that all three depend on) is not done — it needs a new published package and coordinated version bumps across three pluginsTracked, not fixed here. records the source and the re-sync rule; the grading contract that both graders must implement is owned by the test side

0.1.1

Three must-fix items plus a provenance resync, from an independent audit by the build side. Every entry carries an anchor, and the anchors are written to record the failure each fix removed, so it cannot return quietly.

#What was observedWhat the fix is
1Rule B's "execution family" included write/edit, so the ordinary coding loop — look, then change — scored +0.3 every time; stacked with rule A's density score it crossed the line: read×3→write = 0.40, read×5→edit = 0.60, both suspicious. Measured: 4 of 8 ordinary sessions did not stay normalThe execution family is narrowed to code execution (bash/pwsh/run_code/shell/execute/node/python). Afterwards 8 of 9 ordinary sessions stay normal, while read×3→bash is still suspicious — the genuine shape survives. Anchors: the two §1 阳性锚 cases and §3
2isError was treated as "an upgrade was refused": routine failures fed rule C, so two failed writes (ENOSPC) reached 0.80 ⇒ critical — and a critical session with vetoOnCritical is locked out, turning "the disk is full" into "the guard has halted me"Added denyPattern (default: guard refusal wording <plugin> denied); only guard-shaped failures count. This is a heuristic and is declared as one in DEVIATIONS §2. Anchors: §2 阳性锚 plus §2 阴性锚, which proves a real refusal still scores — the fix did not throw the true signal away with the noise
3lib/ledger.js was a stale copy of shape-guard 0.1.1, silently lacking the 0.1.4 fork-aware grading (liveForks / discontinuities / dangling-link rule / seal-bounded findings). One file existed in two versions on one machine, and later fixes would not have propagatedRe-synced wholesale to 0.1.4 (sha256 now matches the source), with provenance and maintenance rules recorded in lib/VENDORED.md
4An invalid windowSize fell back silently: "5" or 10.5 quietly became 10, so a deployment believed it had set a windowInvalid values now throw, surfacing the config error at load time. Anchor: §5
5Two non-equivalent port points were declared "ported verbatim": rule B's families are (upstream's prelude is seven literals; the intersection is only / — upstream scores 0.00 on where this port scores 0.30), and the ordering constraint is (upstream is pure presence)

0.1.0 (2026-10-03)

  • First cut: faithful tracker port plus the dsh wiring (tools/result signal source, optional veto, read-only tool and command, shared-chain threat_level events).
  • Declared deviations (as in the design note): upstream's intent signals are supplied here by tool-settlement events; plan_gate.py's "target-shape ∧ verb" predicate is not ported (dsh has no decompose face; a target allowlist is a separate ticket).
  • Superseded by 0.1.1, which corrects the "verbatim" claim for rule B.

License

MIT © Wang Miaosheng (ORCID: 0009-0003-2767-2421)

lib/VENDORED.md
not isomorphic
cat
ls
[read_file, read_file, bash]
new here
DEVIATIONS.md added: an 18-row item-by-item comparison naming all five deviations with reasons and anchors