Advisory: the plugin-install path needs guardrails — consolidated from #1404/#1197/#1486/#1415/#1413 #1496
Replies: 4 comments
|
插件安装路径缺护栏——合并 5 帖的系统性梳理很有价值(悬空引用/静默禁用/无验证安装)。 这和我们在第 13 章整理的"插件安全审计清单"是同一主题的两端:官方做安装护栏(技术防线),用户侧做装前检查(dsh-plugin-doctor 这类工具 + 审计习惯)。 第 13 章清单:https://github.com/Electricitysheep/dsh-handbook/blob/main/docs/13-security.md |
|
Thanks — the "official install guardrails (technical line) + user-side pre-install checks (tooling + audit habits)" framing is a good split, and the two genuinely complement each other. One user-side tool that fits the "dsh-plugin-doctor" niche already exists: the offline pre-boot checker It complements, rather than conflicts with, a future official |
|
感谢补充——check-dsh-profile.mjs 这个定位很清晰:装前跑一次就知道下次 boot 会不会崩,比事后排障划算得多。"用户侧先行、官方侧后续"这个节奏我也认同,官方 dsh doctor 值得做,但社区的 check 工具能先把坑填上。 已把这个工具收录进手册第 13 章(插件安全审计的配套工具)——顺带建议:如果方便的话把检测覆盖写成文档(当前 #1404 类 → 计划扩展 #1197 悬空引用/#1486 宿主重复),方便其他人接着扩展。https://github.com/Electricitysheep/dsh-handbook/blob/main/docs/13-security.md |
|
Thanks for including it! Done as suggested — the detection coverage is now documented in the script's header comment (it travels with the script, so anyone extending it sees it directly):
Will implement (b)/(c) when I get a chance. Keep up the great work on the handbook — chapter 13 is solid! |
Uh oh!
There was an error while loading. Please reload this page.
Advisory: the plugin-install path needs guardrails
Audience: DeepSeek Harness maintainers
Background: consolidated from five GitHub Discussions on 2026-08-14 (#1404, #1197, #1486, #1415, #1413), several independently reproduced against the real packages (0.1.0-rc.6).
Core conclusion: the plugin ecosystem (
dsh plugin+ pnpm + cordis loader) is currently "fragile by install" — a singledsh plugin addcan take down the whole profile at boot or at runtime, and there is no effective diagnostic. This is not a set of one-off bugs; it is a class of missing guardrails around one shared surface.1. Failure inventory (by severity)
P0 · Boot crashes — the entire profile fails to start
dsh webdies withduplicate loader entry id: <id>; every plugin goes down with itdsh plugin add's reconcile promotes everydsh.bundle-declaring dependency (including pre-existing ones) into the bundle stack, but never cleans up the now-redundant inserts in the user patch (cordis.patch.yml) — the same entry id is inserted twiceERR_MODULE_NOT_FOUND; whole plugin tree diesdsh.profile.bundles, not toname:in patch inserts; combined with vanishedfile:links / packages not on the profile's resolution chain — no validation, no degradationCommon thread: the loader composes without validation and without degradation — duplicate ids and resolution failures both throw the entire tree (
Promise.allSettled→ throw first failure). Anddsh --profile web --dump-confignever mounts the loader / never imports entries, so it is a false-positive check (verified: it exits 0 with the profile in a state that crashes on real boot).P0 · Runtime crashes — boots fine, core functionality dies
Cannot read properties of undefined (reading 'prepare'), UI shows "本轮运行失败"@deepseek-ai/*deps into the profile's top-level node_modules → two module instances of e.g. dsh-tools in one process; module-localSymbol('x')is not equal across instances →ctx.tools[symbol]is undefinedHost Cordis inspect provider "Service" is already registered; conversation unrecoverable until restartCordisInspectRegistryServiceis a process-global singleton butregister()is not idempotent; two sessions mountingdsh-tool-cordisin one process collide (abnormal teardown leaks the ids — disposers only run on clean teardown). Independently reproduced against the real packagesP1 · Ecosystem & diagnostics gaps
dsh doctor/dsh checkfile:links)pnpm-missing messagedsh pluginonly says "pnpm not found on PATH" without concrete commands (corepack enable pnpm/npm i -g pnpm)2. Root causes (six)
dsh plugin/pnpm mutate profile state without guardrails — reconcile scans the whole installed state (not the diff), pnpm hoisting is uncontrolled,file:links have no lifecycle management;@deepseek-ai/*— framework install and profile node_modules copies can both load;--dump-configis insufficient; there is no offline check.3. Recommendations (by priority)
P0 · Stop the bleeding — "install a plugin" should never brick the profile
1. Reconcile must be aware of the user patch (fixes #1404)
.bak, as a human fix did), orbeforeDeps); pre-existing deps keep their current loading mechanism.2. Loader: prevent + report (fixes #1404/#1197)
TypeError;3. Use the global symbol registry across the framework (fixes #1486)
Symbol('@deepseek-ai/...')withSymbol.for(...)in every@deepseek-ai/*package (dsh-toolsTOOL_RUNTIME_SCHEDULER, cosmokit, dsh-llm, dsh-settings, schemastery, …). Minimal and robust.4. Idempotent registration/mounting (fixes #1415)
CordisInspectRegistryService.register()idempotent (reference-counted, or replace-and-return-disposer), or register the first-party inspect providers once on the host plane;P1 · Diagnostics & experience — let users self-check and self-heal
5. Add
dsh doctor/dsh check— offline profile scan reporting:name:from the profile anchor (dsh web fails to boot: unresolvable plugin reference in profile patch (cordis.patch.yml) #1197 class);@deepseek-ai/*packages duplicated against the framework (Tool layer fails with "Cannot read properties of undefined (reading 'prepare')" after installing third-party plugins #1486 class);file:deps with the lockfile/disk (dsh web fails to boot: unresolvable plugin reference in profile patch (cordis.patch.yml) #1197 class).6.
--dump-config --verify-import— actually mount the loader / import every entry, turning the false-positive dump into a real check (both #1197 and #1404 reporters were misled by a passing dump).7. Install UX
pnpminstall commands when missing (corepack enable pnpm/npm i -g pnpm) — dshmarket already does this;dsh plugin add, tell the user it needs a restart to take effect, and how to verify (dsh doctor/ real boot).P2 · Architecture (long-term)
8. Unify resolution (fixes #1197) — give patch-insert
name:the same two-anchor resolution as bundles (install anchor → profile dir), so identical references resolve identically.9. Prevent
@deepseek-ai/*duplication (fixes #1486) — prefer the framework copy in the loader/dsh pluginflow, or dedupe on install; at minimum document that plugins must not directly depend on framework-internal packages (e.g.@deepseek-ai/dsh-tools), and havedsh doctordetect it.10. Install → verify → rollback — after
dsh plugin add, run an automated verification (real boot or equivalent); on failure, offer a rollback command. The plugin-market UI can do the same (validate after one-click install).Tests
11. Regression matrix — each case asserts "profile still boots clean after the install":
dsh plugin add <other>→ dep is NOT promoted, boot stays clean;file:link + patch insert → skip-and-warn or clear error;@deepseek-ai/dsh-tools→ tool calls still work (single-instance assertion).4. Community assets ready to adopt
check-dsh-profile.mjspre-boot checkerdsh doctor, covers (a)Symbol.forfix direction5. Closing
"Everything is a Plugin" is a great vision, and the ecosystem is clearly taking off (plugin market, community handbook, active discussions). But right now the cost of a failed install is too high: one
dsh plugin addcan take down the whole workspace, and recovery means hand-editing YAML. The goal of these recommendations is deliberately modest — make installing plugins safe, diagnosable, and rollback-able. We'd be glad to help test and contribute seed implementations as the team works through P0 → P1 → P2.Consolidated from: #1404, #1197, #1486, #1415, #1413 (deepseek-ai/deepseek-harness Discussions).
All reactions