Repository navigation
Replies: 3 comments
|
This is a good catch and the enforcement facts check out against Which predicate the gate uses
semver.satisfies(runtimeVersion, requirement, { includePrerelease: true })
Control on the same setup with an exactly-wrong peer ( One further npm behaviour, same range, project with no runtime present: the install reports success and auto-installs Admitted sets over all 31 published
|
| range | gate admits | plain semver admits |
|---|---|---|
^0.2.0 |
1 (0.2.1-alpha.1) |
0 |
^0.2.0-rc.2 |
2 (0.2.0-rc.2, 0.2.1-alpha.1) |
1 (0.2.0-rc.2) |
>=0.1.7-alpha.1 <0.2.0 |
6 (…0.2.0-rc.1, 0.2.0-rc.2) |
4 (…0.1.7-rc.2) |
>=0.1.7-alpha.1 <0.2.0 || >=0.2.0-rc.1 <0.2.0 |
6 | 6 — identical |
>=0.1.2 <0.2.0-0 |
12 | 0 |
Over a 17-version × 10-range matrix, no case where plain admits and the gate refuses; 56 cases the other way, every one a prerelease version. The two readings can therefore only disagree in one direction, and ^0.2.0 is stronger than "excludes the rc host": its admitted set is empty for anyone resolving with plain semver, while the gate would still admit it on the alpha host.
Two sentences I would add to your delta
Your four items are the right ones. Both additions are about which reader:
- The prerelease rule is a property of the checking implementation, not of the range: the gate and pnpm admit
>=0.1.7-alpha.1 <0.2.0on a0.2.0-rc.2host, while npm refuses the same pair. - Give the rule, not only an example: declare a range whose admitted set is the same under both readings, which in practice means one explicit union segment per line —
>=0.1.7-alpha.1 <0.2.0 || >=0.2.0-rc.1 <0.2.0. That is the form I use for our own plugins, for exactly this reason.
Also worth one line on the page: this is checkable without re-deriving the semantics — getDshRuntimeVersion() and evaluatePluginCompatibility() are exported from @deepseek-ai/dsh-app-boot (packages/boot/app-boot/src/index.ts:22), so an authoring check can call the gate's own function.
Tooling
Your item 3 is the part a documentation page can only describe. I am packaging the author-side version — given a plugin directory and a host version, it reports each declared dsh peer range's admitted set under the gate predicate and under plain semver, flags the ones where the two disagree, and names the range form that makes them agree — and will report back in this thread.
Scope of the measurements
Plain projects with tarball specs, pnpm 11.13.1 and npm on Node 26.5.0 — not a real profile. dsh plugin add hands its install to pnpm, so the npm column is what an author's own dev checkout hits (the peerDependencies + devDependencies pair publish.md prescribes) and what a user hits installing outside a profile; it is not what a profile does.
|
The compatibility gap now has an installable form: Follow-up to the reply above. What that reply measured by hand is now a package anyone can call, so an author writing or reviewing a
One line of usage — mount it (it ships a bundle patch, With no arguments inside a profile it audits the dsh peer ranges of the plugins that profile mounts; pass It is deliberately read-only, and it deliberately does not propose a replacement range: a synthesized range can be wider than the one it replaces and still look like a fix, so the honest output of a set comparison is the two sets plus the rule that produces them. Three measured facts it encodes, from the same probe behind the reply above:
Verification behind the release: 51 unit and integration assertions ( If the author guide wants a concrete, checkable recommendation to point at rather than the two-set explanation, the union-of-segments shape and the rule "plain semver must admit every line you claim" are the two that can be checked from the outside — and this tool prints both. |
|
Thanks for taking the time to measure this and turn the findings into
a tool. My original repro focused on the DSH gate; the difference
between profile installs and an author's own npm checkout is an
important part of the author experience that I hadn't covered.
I especially like that the audit shows both admitted sets without
silently proposing a wider compatibility range. The per-line examples
and the exported gate check make the documentation suggestion much
more concrete.
Really appreciate the careful follow-up and the published package.
…On Thu, 08 Oct 2026 17:42:41 -0700, argszero ***@***.***> wrote:
The compatibility gap now has an installable form: @***@***.***
Follow-up to the reply above. What that reply measured by hand is now a package anyone can call, so an author writing or reviewing a @deepseek-ai/dsh-* peer range can get the two admitted sets without reproducing the probe.
- npm: ***@***.***/dsh-peer-range-audit
- source: https://github.com/argszero/dsh-peer-range-audit
One line of usage — mount it (it ships a bundle patch, dsh.bundle.patch: ./cordis.patch.yml), then call the tool:
peer_range_audit {}
With no arguments inside a profile it audits the dsh peer ranges of the plugins that profile mounts; pass manifests (parsed package.json objects) or requirements (bare ranges) for anything else, and versions (e.g. from npm view @deepseek-ai/dsh-agent versions --json) to test a ladder instead of the running version alone. For each declared range it prints the set the gate admits, the set plain semver admits, the divergence, and whether admission of the running version rests on the gate's prerelease reading alone.
It is deliberately read-only, and it deliberately does not propose a replacement range: a synthesized range can be wider than the one it replaces and still look like a fix, so the honest output of a set comparison is the two sets plus the rule that produces them.
Three measured facts it encodes, from the same probe behind the reply above:
- Direction. Over the 31 published versions, nothing is admitted by plain semver and refused by the gate; the gate is a strict superset, and every divergence observed was a prerelease.
- The gate's reader is the profile's reader. pnpm is the profile's installer and agrees with the gate — a clean install on the same range — while npm's resolver raises ERESOLVE. So the plain column describes a dev checkout or an out-of-profile install, not what a profile does.
- A union of one segment per line is what dissolves the divergence. >=0.1.7-rc.2 <0.2.0 || >=0.2.0-rc.2 <0.2.1 names each line's own prerelease floor, so plain semver admits both; the single-segment >=0.1.7-alpha.1 <0.2.0 admits both lines under the gate only. The package holds itself to that shape: test/packaging.spec.mjs asserts that no line it claims needs includePrerelease.
Verification behind the release: 51 unit and integration assertions (npm test), 15 defect-injection arms, all caught (npm run test:inject), and the suite run against both claimed lines by pinning each line's whole peer closure — 23 harness packages per line, with every pin read back after install (npm run test:probe-lines).
If the author guide wants a concrete, checkable recommendation to point at rather than the two-set explanation, the union-of-segments shape and the rule "plain semver must admit every line you claim" are the two that can be checked from the outside — and this tool prints both.
—
Reply to this email directly, [view it on GitHub](#9194?email_source=notifications&email_token=CHDJZC6CL74ZPOHQRWXJIN35TAYADA5CNFSNUABIM5UWIORPF5TWS5BNNB2WEL2ENFZWG5LTONUW63SDN5WW2ZLOOQXTCOBYGI2TSNRWUZZGKYLTN5XKMYLVORUG64VFMV3GK3TUVRTG633UMVZF6Y3MNFRWW#discussioncomment-18825966), or [unsubscribe](https://github.com/notifications/unsubscribe-auth/CHDJZC2OROFZEERUFGEDVND5TAYADAVCNFSNUABJKJSXA33TNF2G64TZHMYTGMZTGA3DKMBZGE5UI2LTMN2XG43JN5XDWMJQHE3TSMBRHCQXMAQ).
You are receiving this because you authored the thread.
|
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
I followed the current official plugin-author docs from
Your first Harness pluginand tested the version-range decision against DSH0.2.0-rc.2and0.2.1-alpha.1.【中文摘要】我们从官方
Your first Harness plugin入口按正常作者路径走了一遍。现在 DSH 已经会在安装和启动时强制检查peerDependencies中@deepseek-ai/dsh*的版本范围,但作者教程只告诉你依赖写在哪里,没有在这里解释版本范围会被宿主实际拦截、预发布版本怎么匹配,以及怎样做正反验证。兼容性规则本身并不缺失,问题是它没有出现在插件作者做这个决定的位置。Context: what changed since #6683
#6683 (Sep 15, 2026) captured the earlier state accurately:
peerDependencieswas the only machine-readable compatibility signal, anddsh plugin adddid not validate it — compatibility had to be checked offline. That was correct then; it is now outdated by product evolution, not refuted.Current DSH enforces the contract:
dsh plugin addchecks the package's@deepseek-ai/dsh/@deepseek-ai/dsh-*peers against the runtime version before pnpm runs — an incompatible peer refuses the operation withnothing was installed, and the refusal carries the plugin name, version, runtime version, unsatisfied peers, and the exactdsh plugin allow-version … --accept-riskremedy.disabled), a denied bundle is skipped and listed inskippedBundles.package@version→ exact runtime grants in the profile'scompatibility.json.evaluatePluginCompatibility()inpackages/boot/app-boot/src/plugin-compatibility.tsmatches every declared dsh peer withsemver.satisfies(runtimeVersion, range, { includePrerelease: true }); documented in the App-boot README § Profiles and Plugin Manager README § Version compatibility and exemptions.So the enforcement itself is no longer the gap. The gap is where a human author meets this contract.
Blind author-journey finding
Starting only from
Your first Harness pluginand following only links a normal author naturally reaches (Basics → Framework → Reference; no repo-wide search, no community answers):peerDependenciesanddevDependencies, "as the harness packages do" —docs/user/develop/basic/publish.md.publish.md's Next steps never reach it.^0.2.0does not include0.2.0-rc.2under the current prerelease-aware gate — and the author journey never warns about this ordering trap.Reproduced evidence
Minimal out-of-tree bundle (
package.jsonwithdsh.bundle,cordis.patch.yml,index.jsimportingdefineToolfrom@deepseek-ai/dsh-tools), tested on isolated installs of0.2.0-rc.2and0.2.1-alpha.1:dsh plugin --profile demo add ./my-plugin, peer"@deepseek-ai/dsh-tools": "^0.2.0-rc.2"--dump-configshows the bundle layer; bounded boot prints the plugin's load marker"0.1.5-rc.3"installation rejected: Plugin … is incompatible with dsh …: peerDependencies {…}+nothing was installed+ exactallow-versionremedy (exit 1)"^0.2.0"on the0.2.0-rc.2hostRange behavior under the current gate (
includePrerelease: true):^0.2.0-rc.2matches both0.2.0-rc.2and0.2.1-alpha.1. A stable lower bound such as^0.2.0excludes the earlier0.2.0-rc.2host, while DSH's explicitincludePrerelease: truebehavior can still admit later prereleases such as0.2.1-alpha.1. (Under default node-semver prerelease filtering, withoutincludePrerelease: true,^0.2.0-rc.2would not match the different tuple0.2.1-alpha.1either — exactly the confusion an author hits with no guidance.)Independent community evidence
Beyond the blind author-journey test, independent community reports show why DSH peer-range selection and prerelease handling matter in practice. Some document authoring mistakes; others show expected rejections of incompatible declarations after upgrades. These reports do not establish that the author guide caused any particular mistake.
peerDependenciesranges admit only the earliest prerelease line, excluding newer prerelease lines; the author replied in thread after the feedback.ERESOLVEwhile each plugin's own tests passed — and fixed versions were published.dsh-better-sidebar@0.16.1failed install resolution: stable-bound DSH ranges such as>=0.1.2 <0.2.0-0cannot select published prerelease siblings (ERR_PNPM_NO_MATCHING_VERSION).^0.2.0above.0.1.2-rc.1 -> 0.1.5-rc.1makes plugins pinned to the older prerelease line fail to load, taking the whole profile down.desktopprofile with 22 third-party bundles, upgrading to 0.2.0-rc.1 flagged 11 as abnormal — theirpeerDependenciesonly declared 0.1.x.@nanmicoder/dsh-agent-teams@0.1.21declares peers only up todsh 0.1.7-rc.2, so on 0.2.0-rc.2 install prints the long incompatibility warning and startup refuses the plugin unlessdsh plugin allow-versionis granted.These reports do not share one root cause: some are authoring mistakes where a declared range was too narrow or silently expired against a newer published line, and some are legitimate incompatibility that the gate correctly exposes to users — not every flagged plugin has a wrong range. Across these cases, selecting and validating compatibility ranges is consequential; whether missing author-guide guidance caused any individual report is unproven.
Taken together, these reports corroborate that peer-range and prerelease compatibility affect real plugin authoring and upgrades; they do not establish a causal link to the documentation gap. The runtime gate now enforces the contract, so surfacing its rules and validation steps where authors declare and test supported host ranges remains a targeted documentation improvement.
Smallest actionable docs delta
Near the existing peerDependencies guidance in
docs/user/develop/basic/publish.md:@deepseek-ai/dsh/@deepseek-ai/dsh-*are enforced at install time and at startup; incompatible plugins are refused or not loaded."@deepseek-ai/dsh-tools": "^0.2.0-rc.2"— prereleases participate in range matching;^0.2.0excludes0.2.0-rc.2.dsh plugin --profile demo add ./my-pluginsucceeds anddsh --profile demo --dump-configshows the layer; unsupported host → the same command refuses withnothing was installedand prints the exactallow-versionremedy.One observation (discoverability signal, not a separate complaint)
The current Agent-assisted plugin-development path was able to derive and validate the correct declaration on its own (bundled skill + host source), while the human author path did not surface the same contract — one gap, two audiences.
References
All reactions