2 Commits
Author SHA1 Message Date
mward4 b7fa429b50 v0.2.1: validated against DSH 0.2.1-alpha.1
No code change from 0.2.0. This release records what was measured and how to
install so the plugin market can see future releases.

Compatibility
- Verified against 0.1.7-rc.2, 0.2.0-rc.1 and 0.2.1-alpha.1.
- dsh-host-webserver, dsh-client-connection and dsh-settings are byte-identical
  between 0.2.0-rc.1 and 0.2.1-alpha.1, so no surface this plugin uses moved.
- --public-url advertises a URL in the printed/handoff/system-prompt forms and
  grants no trust; resolveLanTrust() is a separate function it never reaches.
- A/B over a non-loopback peer on 0.2.1-alpha.1: 7/7 enabled, 1/7 disabled.
- This plugin declares no @deepseek-ai/dsh-* peers, so the harness peer-range
  gate has nothing to reject it on; an in-place profile upgrade boots with it
  installed and no exemption recorded.

Install
- The market resolves the ref the installed spec names, so a tag pin reports
  "up to date" for ever. Documented the branch install (#main) that makes the
  in-app Update button work, and that gitUpdateTarget() leaves the spec alone.
2026-10-04 19:11:52 -04:00
mward4 80fb6b6f4f Note that the frontend ships its own manifest and this one precedes it 2026-09-27 19:42:17 -04:00
2 changed files with 86 additions and 4 deletions

No files matched your search

+85 -3
View File
@@ -109,6 +109,32 @@ The bundle patch inserts the row automatically. Verify it loaded:
dsh plugin --profile web list | grep trustworthy
```
### Installing so that the market can update it
The plugin market decides whether a git-sourced install has an update by
resolving **the ref the installed spec names** — `checkUpdates()` in
`dshmarket` calls `resolveGitRemoteHead(spec, gitRefOfTarget(spec))`. A spec
pinned to a tag therefore reports "up to date" for ever, however many releases
are published: the check resolves tag `v0.2.0` and compares it with the very
commit it already installed. Publishing a new tag does not make a button
appear.
To receive in-app updates, install from the branch:
```bash
dsh plugin --profile web add 'git+https://gitea.milesward.dev/mward4/dsh-trustworthy.git#main'
```
Releases are still tagged (`v0.2.1`, `v0.2.0`, …) so you can pin to one
deliberately and move by hand; the branch ref is what makes the market's
**Update** button work. Applying an update leaves the spec alone —
`gitUpdateTarget()` strips a fragment only when it is a 40-hex commit pin — so
it stays on the branch and keeps following it.
`dshmarket` caches its update verdicts in memory for 30 minutes; the market page
forces a fresh check when it opens, and `GET /dsh-market/updates?force=1` does
the same on demand.
---
## Configuration
@@ -195,6 +221,16 @@ secure contexts; the clipboard falls back to a hidden textarea and
viewport tag to `viewport-fit=cover` so Add to Home Screen produces a
standalone app rather than a bookmark.
Note that the harness frontend **already ships a manifest** — a static
`manifest.webmanifest` with `display: "fullscreen"`, linked relatively from its
own `index.html` and served from the fallback seat. So a page with `shimPwa` on
carries two `rel="manifest"` links. That is harmless but worth knowing: the
browser takes the **first** link in document order, and index injections land at
the top of `<head>`, so this plugin's manifest is the one that wins — reporting
`display: "standalone"`, which keeps the status bar that `fullscreen` hides.
Nothing is string-patched to achieve it; the added link simply precedes the
shipped one.
The harness's own code no longer needs either shim — `@deepseek-ai/dsh-util-crypto`
mints UUIDs from `getRandomValues`, and its lint rules point callers there — but
third-party plugin bundles are not obliged to, and one that shipped recently
@@ -205,9 +241,9 @@ three are `true` by default; serving over HTTPS makes the first two redundant.
## Compatibility
Verified against **DSH 0.1.7-rc.2**. The plugin depends on three things that
are internal rather than public API, so a harness release that renames any of
them will break it:
Verified against **DSH 0.1.7-rc.2**, **0.2.0-rc.1**, and **0.2.1-alpha.1**. The
plugin depends on three things that are internal rather than public API, so a
harness release that renames any of them will break it:
| Depends on | Where |
|---|---|
@@ -227,6 +263,37 @@ interceptor was not installed and a Host fence will still refuse a remote
window; the harness surface may have changed
```
### What was checked on 0.2.1-alpha.1
The three packages this plugin reaches into are **byte-identical** between
0.2.0-rc.1 and 0.2.1-alpha.1 — `dsh-host-webserver/lib/index.js`
(`48605e6f4fc88362c07569686df1417b`), `dsh-client-connection/lib/index.js`
(`39d2d6d64f3ffb91ec623932a15a068b`), and `dsh-settings/lib/index.js`
(`5024d014ad19237fb91fbf8bb4370903`) — so nothing in the table above has moved,
`ownsHost` is still read by the client bundle, and the `webserver/index-inject`
channel is still emitted and still typed.
The release does add `--public-url`, and it is worth being explicit about what
it is not: it advertises an HTTP root in the printed URL, the system prompt, and
`DSH_WEB_URL`, and it **grants no trust** — the CLI's own help says so. The trust
surface is a separate function, `resolveLanTrust()`, and `publicUrl` never
reaches it. `--public-url` does not replace this plugin.
Measured on 0.2.1-alpha.1 over a non-loopback peer, plugin enabled vs.
`enabled: false`, same harness and same profile: **7/7 with it on, 1/7 with it
off**. Switched off, the shell answers 401, the Skill Center answers 400 (the
fence's own throw), the shims are absent, and the ready URL carries a process
token again. That difference is the whole of what this plugin carries.
An in-place upgrade of a real 0.2.0-rc.1 profile to 0.2.1-alpha.1 boots and
serves with this plugin installed and no version exemption recorded. Two other
plugins are refused by the harness's peer-range gate on that release —
`@memtensor/memos-local-plugin` and `@michengai/dsh-btw`, both because of an
absolute `<0.2.0` / `… || 0.2.0-rc.2` upper bound in their `@deepseek-ai/dsh-*`
peers. This plugin declares **no `@deepseek-ai/dsh-*` peers at all**
(`peerDependencies` is `@deepseek-ai/schemastery` only), so the gate has nothing
to reject it on and it skips nothing at boot.
### Why it never writes the trusted-host lists
The obvious fix for this problem is to add the arriving host to
@@ -361,6 +428,11 @@ node test/shims.test.mjs # executes the generated shim in a context without
node scripts/live-probe.mjs # against the running harness, over a non-loopback peer
```
All four suites together — **52 tests** (fence 8, apply 20, handover 15,
shims 9) — are `node --test test/*.test.mjs` from the plugin directory. The
shell has to expand that glob: `node --test test/` fails with `MODULE_NOT_FOUND`
on Node 22.
`test/fence.test.mjs` loads `sameOrigin()` from the installed `dshmarket` when a
profile is present and says which source it used, so a run against a bundled
copy is never mistaken for a run against the real thing. `test/shims.test.mjs`
@@ -376,6 +448,16 @@ resolvable `@deepseek-ai/schemastery` for the second.
address as well as the `Host`, so a probe over `127.0.0.1` can never reproduce a
remote client and always looks like it passes.
## Releases
| Version | What changed |
|---|---|
| **0.2.1** | Documentation and compatibility only — **no code change from 0.2.0**. Records the 0.2.1-alpha.1 validation above, and how to install so the market can update it. |
| 0.2.0 | Renamed from `dsh-disable-untrusted-origin`. Added `lib/handover.js`: originals recorded once on a `Symbol.for` carrier, a liveness check (`fiber.uid === null`) on every delegated path, and an interceptor that retires a tagged predecessor. Capabilities now degrade with a warning instead of failing the fiber. |
| 0.1.2 | Restored `crypto.randomUUID` and `navigator.clipboard` on plain HTTP, added the PWA manifest, and widened the viewport for notched screens. |
| 0.1.1 | Provided the paired-device service, so the Skill Center works over a remote address instead of answering 400. |
| 0.1.0 | First release: one interceptor on the raw server, rewriting request identity to the loopback authority. |
## License
MIT
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "dsh-trustworthy",
"version": "0.2.0",
"version": "0.2.1",
"description": "Removes the untrusted-origin restriction from DeepSeek Harness. Every browser window is treated as if it were running on the harness machine itself: no process token, no declared trusted host, and no per-plugin origin fence, because one interceptor answers every request with the loopback authority.",
"type": "module",
"main": "lib/index.js",