DSHIO-DEV · Development
What a conforming plugin looks like. Six requirements, each with the correct form and the common mistake.
Scope. This standard does not say what a plugin should do —
that is the author's choice. It says what makes a delivered package reliably installable and
loadable.
1. Project structure
An installable plugin needs at least three files:
package.json ← required, declares dsh.bundle cordis.patch.yml ← required, declares the inserted plugin lib/index.js ← required, exports apply(ctx)
| Clause | Requirement |
|---|---|
| 1.1 | main or exports points at a file that exists |
| 1.2 | Do not package node_modules, .git or test files |
| 1.3 | The repo root has a README saying what it does and how to install |
2. Manifest
This is the most common rejection. DSH only recognises
dsh.bundle; dsh.client alone will not install.
Correct:
{
"name": "your-plugin",
"version": "1.0.0",
"dsh": { "bundle": { "patch": "./cordis.patch.yml" } },
"engines": { "dsh": ">=0.2.0" }
}
Wrong (installs but never loads):
{
"dsh": { "client": { "platform": "web" } } // ← no bundle
}
| Clause | Requirement |
|---|---|
| 2.1 | dsh.bundle.patch exists and points at a real file |
| 2.2 | The name in cordis.patch.yml matches the package name |
| 2.3 | engines.dsh sets a lower bound only — never an upper bound |
On 2.3 — the single most common cause of install failure.
❌ "dsh": ">=0.2.0-rc.2 <0.2.2-0" // excludes 0.2.2; fails on the current release ✅ "dsh": ">=0.2.0" // lower bound onlyOf 122 top plugins we tested, 8 could not install because of this upper bound.
3. Permission declaration
Capabilities must be declared, because users judge risk from them.
| Value | Meaning | Risk |
|---|---|---|
none | No external access | Low |
network | Makes network requests | Medium |
filesystem | Reads or writes workspace files | High |
shell | Executes system commands | High |
device | Accesses hardware | High |
| Clause | Requirement |
|---|---|
| 3.1 | List the permissions used in the README |
| 3.2 | Do not declare permissions you do not use |
| 3.3 | With several permissions, risk takes the highest |
4. Versioning
| Clause | Requirement |
|---|---|
| 4.1 | Follow SemVer |
| 4.2 | Document breaking changes and raise the engines.dsh lower bound |
| 4.3 | Never re-publish an existing version number |
5. Error handling
The DSH loader in older versions could reject the whole load tree when one plugin throws.
| Clause | Requirement |
|---|---|
| 5.1 | Wrap fallible steps in apply(ctx) with try/catch |
| 5.2 | Degrade or disable yourself when a dependency is missing; do not throw into the host |
| 5.3 | Error messages must be locatable: plugin name and failing step |
6. Security red lines
Violating any one means permanent removal from the index.
| Clause | Prohibited |
|---|---|
| 6.1 | Writing to system paths outside the workspace |
| 6.2 | Reading or uploading user credentials |
| 6.3 | Creating persistent processes or scheduled tasks without explicit consent |
| 6.4 | Sending user data to third parties without disclosure and an off switch |
| 6.5 | Running destructive commands at install time |
| 6.6 | Impersonating an official plugin |
Self-check before release
[ ] package.json declares dsh.bundle.patch [ ] cordis.patch.yml name matches the package name [ ] engines.dsh sets a lower bound only [ ] README lists declared permissions [ ] No unused permissions declared [ ] apply() wraps fallible steps in try/catch [ ] None of 6.1 - 6.6 violated
Next
Self-test against DSHIO-TEST, then take the grade from DSHIO-GRADE.
Version history
| Version | Standard No. | Published | Change |
|---|---|---|---|
| v1.0 | DSHIO/T 01—2026 | 2026-11-06 | First release |
The version increments on any clause change; older versions remain available.