upstream-radar 0.40.0 → 0.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +123 -225
- package/dist/src/cli.js +11 -2
- package/dist/src/cli.js.map +1 -1
- package/dist/src/dsh-compatibility-ir.d.ts +98 -0
- package/dist/src/dsh-compatibility-ir.d.ts.map +1 -0
- package/dist/src/dsh-compatibility-ir.js +389 -0
- package/dist/src/dsh-compatibility-ir.js.map +1 -0
- package/dist/src/dsh-compatibility-issues.d.ts +44 -0
- package/dist/src/dsh-compatibility-issues.d.ts.map +1 -0
- package/dist/src/dsh-compatibility-issues.js +185 -0
- package/dist/src/dsh-compatibility-issues.js.map +1 -0
- package/dist/src/dsh-compatibility-ledger.d.ts +150 -0
- package/dist/src/dsh-compatibility-ledger.d.ts.map +1 -0
- package/dist/src/dsh-compatibility-ledger.js +645 -0
- package/dist/src/dsh-compatibility-ledger.js.map +1 -0
- package/dist/src/dsh-install-observation.d.ts +88 -1
- package/dist/src/dsh-install-observation.d.ts.map +1 -1
- package/dist/src/dsh-install-observation.js +579 -6
- package/dist/src/dsh-install-observation.js.map +1 -1
- package/dist/src/dsh-install-plan.d.ts +16 -6
- package/dist/src/dsh-install-plan.d.ts.map +1 -1
- package/dist/src/dsh-install-plan.js +272 -46
- package/dist/src/dsh-install-plan.js.map +1 -1
- package/dist/src/dsh-plugin.d.ts.map +1 -1
- package/dist/src/dsh-plugin.js +6 -2
- package/dist/src/dsh-plugin.js.map +1 -1
- package/dist/src/dsh-runtime.d.ts +6 -0
- package/dist/src/dsh-runtime.d.ts.map +1 -1
- package/dist/src/dsh-runtime.js +38 -0
- package/dist/src/dsh-runtime.js.map +1 -1
- package/dist/src/index.d.ts +7 -4
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/installed-graph.d.ts.map +1 -1
- package/dist/src/installed-graph.js +105 -26
- package/dist/src/installed-graph.js.map +1 -1
- package/dist/src/radar-types.d.ts +15 -0
- package/dist/src/radar-types.d.ts.map +1 -1
- package/dist/src/semver.d.ts.map +1 -1
- package/dist/src/semver.js +7 -1
- package/dist/src/semver.js.map +1 -1
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/docs/README.zh-CN.md +25 -23
- package/package.json +1 -1
- package/schemas/dsh-compatibility-ir.schema.json +89 -0
- package/schemas/dsh-install-observation.schema.json +135 -2
package/README.md
CHANGED
|
@@ -2,258 +2,155 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://github.com/MicroMilo/upstream-radar/actions)
|
|
4
4
|
[](https://www.npmjs.com/package/upstream-radar)
|
|
5
|
+
[](https://github.com/MicroMilo/upstream-radar/stargazers)
|
|
5
6
|
[](LICENSE)
|
|
6
7
|
|
|
7
|
-
**
|
|
8
|
+
**Compatibility evidence for the [DeepSeek Harness (DSH)](https://github.com/deepseek-ai/deepseek-harness) plugin ecosystem.**
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
A plugin repository can look healthy while its published artifact has drifted
|
|
11
|
+
from the DSH host it actually runs in. Upstream Radar joins what a plugin
|
|
12
|
+
declares with what an isolated DSH profile really resolves, then keeps that
|
|
13
|
+
relationship current as DSH and plugins change.
|
|
10
14
|
|
|
11
|
-
|
|
12
|
-
| --- | --- |
|
|
13
|
-
| **DSH compatibility / admission** | Whether the exact published bundle can be installed, registered, and loaded by the DSH releases you care about, with an isolated execution lane for behavior evidence. |
|
|
14
|
-
| **Real dependency graph** | Which exact package versions and physical paths the plugin brings into the DSH profile, including unresolved edges. |
|
|
15
|
-
| **Continuous upstream monitoring** | Whether an advisory, npm release, DSH/Cordis change, or breaking signal changes the old → new situation. |
|
|
16
|
-
| **Author-facing repair** | Which plugin, dependency path, version, lockfile, or DSH declaration gives the author a concrete next fix. |
|
|
17
|
-
|
|
18
|
-
The deterministic scanner establishes package, graph, advisory, and compatibility facts. Only a meaningful affected change is handed to the DSH Agent for read-only, project-specific analysis; the model does not guess version matches or replace the evidence.
|
|
15
|
+
The core object is an exact environment, not a package name or a diff:
|
|
19
16
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
```mermaid
|
|
23
|
-
flowchart TD
|
|
24
|
-
A["DSH plugin source or exact npm artifact"] --> B["Static review + DSH compatibility check"]
|
|
25
|
-
B --> C["Build the real plugin → dependency graph"]
|
|
26
|
-
C --> D["Monitor advisories, npm, DSH and Cordis changes"]
|
|
27
|
-
D --> E{"Meaningful affected change?"}
|
|
28
|
-
E -- "No" --> F["Update observation point and stay quiet"]
|
|
29
|
-
E -- "Yes" --> G["Calculate exact old → new impact paths"]
|
|
30
|
-
G --> H["Send bounded evidence to the DSH Agent"]
|
|
31
|
-
H --> I["Return a repairable action to the plugin author"]
|
|
17
|
+
```text
|
|
18
|
+
plugin tarball SHA-256 × DSH version × Node/pnpm baseline × approved dependency builds
|
|
32
19
|
```
|
|
33
20
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
## The upstream/downstream alignment IR
|
|
37
|
-
|
|
38
|
-
Every observer snapshot now carries a small, machine-readable alignment record:
|
|
21
|
+
## How the system fits together
|
|
39
22
|
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
23
|
+
```mermaid
|
|
24
|
+
flowchart TB
|
|
25
|
+
Artifact["Exact plugin tarball"] --> Static["Static: peer declaration + literal import evidence"]
|
|
26
|
+
DSH["Exact DSH + Node runtime"] --> Runtime["Fresh VM + restricted container"]
|
|
27
|
+
Static --> Runtime
|
|
28
|
+
Runtime --> Resolve["Dynamic: install → register → profile resolver → import → headless boot"]
|
|
29
|
+
Resolve --> IR["Compatibility IR: declared range ↔ resolved host version"]
|
|
30
|
+
IR --> Ledger["Current-cell ledger"]
|
|
31
|
+
IR --> Impact["Reverse impact index + author-facing repair"]
|
|
32
|
+
Ledger --> Incident["Managed compatibility incident"]
|
|
33
|
+
Incident --> Repair["Plugin or DSH repair"]
|
|
34
|
+
Repair --> Artifact
|
|
44
35
|
```
|
|
45
36
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
37
|
+
Radar establishes deterministic facts; an optional Agent may explain project
|
|
38
|
+
impact afterward. A model never decides whether versions match or turns missing
|
|
39
|
+
evidence into a green result.
|
|
49
40
|
|
|
50
|
-
|
|
51
|
-
source: dsh-lark-bot@0.15.8
|
|
52
|
-
published: dsh-feishu-bot@0.15.8
|
|
53
|
-
graph root: dsh-lark-bot@0.15.8
|
|
54
|
-
result: mismatch
|
|
55
|
-
```
|
|
41
|
+
## What it answers
|
|
56
42
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
43
|
+
| Question | Evidence returned |
|
|
44
|
+
| --- | --- |
|
|
45
|
+
| Does the declared plugin contract align with this DSH release? | Exact tarball, Node contract, install/registration/load evidence, and every direct peer's resolved host version. |
|
|
46
|
+
| Is it a runtime break or a declaration drift? | Static literal-import classification beside the dynamic resolver result. |
|
|
47
|
+
| What enters the DSH profile? | Exact npm/pnpm nodes, host-plane joins, duplicate versions, paths, and unresolved edges. |
|
|
48
|
+
| Which plugins are exposed to an upstream dependency change? | A materialized reverse index from host package to exact plugin cells. |
|
|
49
|
+
| What can the author repair? | One package/range/API boundary with the evidence needed to reproduce it. |
|
|
50
|
+
| What happens after a break is found? | One managed issue is created, updated on repeat failures, reopened on regression, and closed only after a clean retest. |
|
|
51
|
+
|
|
52
|
+
## Proven on real DSH plugins
|
|
53
|
+
|
|
54
|
+
- Imported a commit-pinned cohort of **8 repositories** from
|
|
55
|
+
[`awesome-dsh-plugin`](examples/dsh/awesome-observer/README.md); 6 independently
|
|
56
|
+
matched npm artifacts enter the isolated matrix and 2 remain correctly
|
|
57
|
+
GitHub-only.
|
|
58
|
+
- In a fresh VM, tested `@zseven-w/dsh-openpencil@0.1.0-rc.1` against current
|
|
59
|
+
DSH `0.1.1-rc.1` on Node 24. Install, registration, direct import, and
|
|
60
|
+
headless boot passed; the exact host-contract check found **12/14** peers
|
|
61
|
+
aligned, one type-only peer declaration missing, and one runtime `react-dom`
|
|
62
|
+
range drift. [Read the reproducible case.](examples/dsh/install-observer/reports/2026-08-22-openpencil-node24.md)
|
|
63
|
+
- Proved `dsh-better-sidebar@0.14.0` succeeds only after the documented
|
|
64
|
+
`node-pty` build is explicitly approved and the native toolchain is present.
|
|
65
|
+
- Found that `@sanqi-normal/dsh-webui-market-plugin@0.5.4` could not form a
|
|
66
|
+
clean DSH dependency graph, gave the author an exact repair path, and added
|
|
67
|
+
the published `0.5.5` repair to the maintained isolated matrix.
|
|
68
|
+
[See the author-confirmed case.](https://github.com/Sanqi-normal/dsh-webui-market-plugin/issues/5)
|
|
69
|
+
- Built a reverse index from **37 real plugin graphs and 1,025 dependency
|
|
70
|
+
coordinates**, while preserving 13 missing-graph targets as evidence gaps.
|
|
71
|
+
|
|
72
|
+
Read the [live isolated matrix and negative controls](examples/dsh/install-observer/reports/2026-08-21-dsh-0.1.1-rc.1.md)
|
|
73
|
+
or inspect the [first 50-plugin corpus](examples/dsh/first-batch/README.md).
|
|
61
74
|
|
|
62
75
|
## Try it in 60 seconds
|
|
63
76
|
|
|
64
77
|
```bash
|
|
65
|
-
#
|
|
66
|
-
npx --yes upstream-radar@0.
|
|
78
|
+
# Network-free product walkthrough
|
|
79
|
+
npx --yes upstream-radar@0.41.0 demo
|
|
67
80
|
|
|
68
|
-
#
|
|
69
|
-
npx --yes upstream-radar@0.
|
|
81
|
+
# Static review of a public DSH plugin; no install or plugin execution
|
|
82
|
+
npx --yes upstream-radar@0.41.0 scan \
|
|
70
83
|
https://github.com/PlutoKeating/dsh-lark-bot \
|
|
71
84
|
--fail-on never
|
|
72
85
|
|
|
73
|
-
#
|
|
74
|
-
npx --yes upstream-radar@0.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
The important output is evidence, not a green badge: exact package identity, dependency paths, unresolved edges, install-time scripts, npm integrity/signature/provenance, advisory matches, and DSH load results.
|
|
79
|
-
|
|
80
|
-
## The isolated execution lane
|
|
81
|
-
|
|
82
|
-
Static metadata tells us that a lifecycle script exists; it cannot tell us what
|
|
83
|
-
actually ran. The new [`dsh-install` workflow](.github/workflows/observe-dsh-plugin-install.yml)
|
|
84
|
-
therefore uses a separate, deliberately untrusted lane:
|
|
85
|
-
|
|
86
|
-
```text
|
|
87
|
-
fresh GitHub-hosted VM (no secrets, read-only repository token)
|
|
88
|
-
→ restricted container (no host workspace or Docker socket)
|
|
89
|
-
→ npm pack exact package@version with scripts disabled
|
|
90
|
-
→ enforce the artifact's declared Node range before plugin code can run
|
|
91
|
-
→ record the exact Node and pnpm runtime used by the check
|
|
92
|
-
→ DSH installs that same tarball with only the declared dependency-build approvals
|
|
93
|
-
→ strace records child processes, network destinations and file writes
|
|
94
|
-
→ DSH loads the registered bundle under the same exact release
|
|
95
|
-
→ bounded JSON report survives and a non-compatible pair fails the check
|
|
96
|
-
→ the container and VM are discarded
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
Use **Actions → Observe one DSH plugin install** and supply one exact plugin and
|
|
100
|
-
one exact DSH version. The CLI also exposes `probe dsh-install`, but it refuses
|
|
101
|
-
to run unless both `--execute` and `UPSTREAM_RADAR_ISOLATED_RUNNER=1` are present;
|
|
102
|
-
it is not intended as a normal laptop command.
|
|
103
|
-
|
|
104
|
-
This lane is wired into the always-on observer. Radar now watches the official
|
|
105
|
-
`@deepseek-ai/dsh` `next` release channel (current DSH releases are prereleases
|
|
106
|
-
rather than npm `latest`). A new exact DSH publication fans out the
|
|
107
|
-
[nine-plugin maintained corpus](examples/dsh/install-observer/targets.json), one
|
|
108
|
-
fresh VM per plugin. Six of those targets come from an identity-checked,
|
|
109
|
-
[commit-pinned `awesome-dsh-plugin` cohort](examples/dsh/awesome-observer/README.md);
|
|
110
|
-
two additional catalog targets are source-only because their real distribution
|
|
111
|
-
is GitHub rather than npm. A mapped plugin publication retests only that plugin. Unchanged
|
|
112
|
-
evidence keeps `observations.json` byte-stable, persistent source/publish drift
|
|
113
|
-
does not wake the Agent again, and the DSH Agent/API key never enters the execution job.
|
|
114
|
-
Build-script approvals are exact package names stored in the maintained target
|
|
115
|
-
and copied into every report; an absent list approves nothing.
|
|
116
|
-
|
|
117
|
-
The first implementation is intentionally honest about its limit: a container
|
|
118
|
-
shares the hosted VM's kernel, and same-container `strace` evidence is not
|
|
119
|
-
tamper-proof against determined malicious code. The outer VM is disposable and
|
|
120
|
-
secret-free; a Firecracker collector is the later high-assurance backend, not a
|
|
121
|
-
claim made by this report. See the [execution boundary and result semantics](examples/dsh/install-observer/README.md)
|
|
122
|
-
and [`dsh-install-observation.schema.json`](schemas/dsh-install-observation.schema.json).
|
|
123
|
-
|
|
124
|
-
## What we have already found
|
|
125
|
-
|
|
126
|
-
These are real, reproducible cases in this repository—not synthetic “vulnerable package” demos.
|
|
127
|
-
|
|
128
|
-
| Case | Finding | Why it matters |
|
|
129
|
-
| --- | --- | --- |
|
|
130
|
-
| [Live DSH `0.1.1-rc.1` isolated matrix](examples/dsh/install-observer/reports/2026-08-21-dsh-0.1.1-rc.1.md) | Eight exact artifacts install/register/load under their recorded contracts; OpenPencil is stopped before execution because it requires Node ≥24.11 while the isolated runner is Node 22.23; Better Sidebar passes only with its documented `node-pty` build approval and a real native toolchain | The imported awesome cohort found both a genuine runtime-pair incompatibility and a test-environment defect, while preserving the evidence that distinguishes them. |
|
|
131
|
-
| [`dsh-cloudflare-browser-run@0.1.1`](examples/reports/dsh-cloudflare-browser-run-0.1.1.txt) | 18 resolved packages, 2 unresolved optional Cordis edges, 0 known vulnerabilities, and DSH rc.6/rc.7 both loaded the bundle | A real browser plugin demonstrates the DSH admission boundary and why incomplete edges stay visible. |
|
|
132
|
-
| [50-plugin batch](examples/dsh/reports/dsh-batch-50-2026-08-17.md) / [real graph corpus](examples/dsh/first-batch/README.md) | 50 source scans, 30 exact npm reviews, 37 real plugin graphs indexed; 13 targets kept as missing evidence | The reverse index is now built from real DSH plugins, and missing graphs are not treated as clean. |
|
|
133
|
-
| [`dsh-feishu-bot@0.15.8`](examples/dsh/reports/dsh-feishu-bot-0.15.8-review-2026-08-18.md) | 89-package graph, 12 unresolved optional edges, reachable `protobufjs` `postinstall`, DSH rc.6/rc.7 compatible | “No known CVE” is not the same as “no installation trust boundary.” |
|
|
134
|
-
| [DSH-TUI source vs npm](examples/dsh/reports/dsh-tui-source-vs-npm-2026-08-18.md) | Source has `prepare`; published artifact does not | Source-only and artifact-only reviews answer different questions. |
|
|
135
|
-
| [dsh-composer-expand](examples/dsh/reports/dsh-composer-expand-lockfile-feedback.md) | Committed lockfile root says `0.1.0` while source says `0.1.2` | A small author-fix can restore the identity of the monitored graph. |
|
|
136
|
-
|
|
137
|
-
We report a confirmed vulnerability only when the affected exact version and runtime path are supported by the available evidence. Development-only hits, missing data, and advisory-source outages remain visibly different states.
|
|
138
|
-
|
|
139
|
-
## Monitor the findings we already found
|
|
140
|
-
|
|
141
|
-
The repository now has a focused watch for seven real DSH plugins from the first
|
|
142
|
-
batch. It re-runs the source scan and the exact npm artifact review, then stores
|
|
143
|
-
only trusted observations in [`state.json`](examples/dsh/finding-watch/state.json)
|
|
144
|
-
and writes the current author-facing result to
|
|
145
|
-
[`report.md`](examples/dsh/finding-watch/report.md).
|
|
146
|
-
|
|
147
|
-
```bash
|
|
148
|
-
pnpm run monitor:dsh-findings
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
The watch distinguishes `persisting`, `added`, `resolved`, `changed`, and
|
|
152
|
-
`unknown`. A failed registry request never becomes “resolved”; a source fix also
|
|
153
|
-
does not erase a finding that remains in the published npm artifact. The same
|
|
154
|
-
loop runs daily in [the dedicated GitHub Actions workflow](.github/workflows/dsh-finding-watch.yml)
|
|
155
|
-
and commits the state only when a trusted observation changes. It does not install
|
|
156
|
-
plugins, execute lifecycle scripts, load DSH, or call an LLM.
|
|
157
|
-
|
|
158
|
-
The current run is already useful: `dsh-msg-hub@0.1.8` has removed the old source
|
|
159
|
-
lockfile findings, but its npm artifact still reaches `protobufjs@7.6.5` with a
|
|
160
|
-
`postinstall`; `dsh-wsl-workspace` now resolves `koffi@3.1.6`, while the native
|
|
161
|
-
install step remains. The other reviewed install/lifecycle findings persist.
|
|
162
|
-
|
|
163
|
-
## The dependency graph behind every alert
|
|
164
|
-
|
|
165
|
-
```text
|
|
166
|
-
plugin@1.0.0
|
|
167
|
-
├── framework@2.4.7
|
|
168
|
-
│ ├── parser@3.2.1
|
|
169
|
-
│ └── archive@1.8.0
|
|
170
|
-
└── logger@4.0.2
|
|
171
|
-
└── parser@2.9.0 ← the affected physical node
|
|
86
|
+
# Exact artifact review plus a DSH load matrix
|
|
87
|
+
npx --yes upstream-radar@0.41.0 review dsh-plugin \
|
|
88
|
+
dsh-cloudflare-browser-run@0.1.3 \
|
|
89
|
+
--dsh-version 0.1.0-rc.8,0.1.1-rc.1
|
|
172
90
|
```
|
|
173
91
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
[`schemas/reverse-dependency-index.schema.json`](schemas/reverse-dependency-index.schema.json).
|
|
215
|
-
|
|
216
|
-
The checked-in real-corpus replay makes this concrete: an observed
|
|
217
|
-
`@deepseek-ai/cordis@4.0.1 → 4.0.2` change routes to 17 DSH plugins from the
|
|
218
|
-
first 50-plugin batch. The route is marked `incomplete` because 26 of the 37
|
|
219
|
-
reconstructed graphs contain unresolved edges; the other 13 targets are kept
|
|
220
|
-
outside the index as missing evidence. Run `pnpm run showcase:observer` to
|
|
221
|
-
replay baseline → one Agent task → quiet run without network access.
|
|
222
|
-
|
|
223
|
-
## GitHub Action
|
|
224
|
-
|
|
225
|
-
The repository already contains a reusable, composite Action in [`action.yml`](action.yml). It runs the same frozen Radar check in CI and writes a short Job Summary.
|
|
226
|
-
|
|
227
|
-
```yaml
|
|
228
|
-
- uses: MicroMilo/upstream-radar@v0.40.0
|
|
229
|
-
with:
|
|
230
|
-
config: upstream-radar.config.json
|
|
231
|
-
fail-on: high
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
See the [consumer workflow](examples/github-actions/consumer/README.md) for config and lockfile examples. The GitHub Marketplace prompt is a distribution opportunity, not a separate scanning engine: the Action listing should follow a reviewed stable release, while exact tags remain copyable and auditable.
|
|
235
|
-
|
|
236
|
-
## What it does—and does not do
|
|
237
|
-
|
|
238
|
-
| It does | It does not claim |
|
|
92
|
+
The code-executing path is deliberately separate. Run **Actions → Observe one
|
|
93
|
+
DSH plugin install** to give one exact pair its own secret-free GitHub-hosted VM
|
|
94
|
+
and restricted container.
|
|
95
|
+
|
|
96
|
+
## Always-on now
|
|
97
|
+
|
|
98
|
+
The scheduled observer watches DSH, plugin source/npm/lockfile evidence every
|
|
99
|
+
day, then reconciles a checked-in **compatibility ledger** against the desired
|
|
100
|
+
current matrix. An isolated run is selected when its exact cell is missing,
|
|
101
|
+
older than seven days, or invalidated by a DSH/plugin coordinate, source graph,
|
|
102
|
+
runtime, or build-policy change. A package update therefore accelerates a
|
|
103
|
+
retest; it is no longer the only trigger.
|
|
104
|
+
|
|
105
|
+
Every report must prove its exact plugin × DSH × Node runtime × build-approval
|
|
106
|
+
cell before it can update the [ledger](compatibility-ledger.json). The Action
|
|
107
|
+
also materializes a bounded [compatibility IR](compatibility-ir.json) and
|
|
108
|
+
[reverse index](compatibility-reverse-index.json). The IR does not copy the
|
|
109
|
+
entire pnpm tree: it preserves the compatibility frontier—the plugin's declared
|
|
110
|
+
non-optional peer range, static use evidence, and concrete package version that
|
|
111
|
+
the final DSH profile resolves.
|
|
112
|
+
|
|
113
|
+
A Node-engine mismatch stops before plugin execution; a maintained target can
|
|
114
|
+
also select its required Node profile explicitly. The profile lockfile and
|
|
115
|
+
effective profile-plus-DSH-host graph are compared on every retest. An
|
|
116
|
+
install/load green result cannot close a cell while a required direct host peer
|
|
117
|
+
is missing, outside its declared range, or indeterminate.
|
|
118
|
+
|
|
119
|
+
When all cells are current, the runtime lane stays quiet. Missing or malformed
|
|
120
|
+
reports never turn green: they remain unsatisfied and are selected again.
|
|
121
|
+
|
|
122
|
+
Actionable incompatibilities become managed issues in the Radar repository.
|
|
123
|
+
The same stable cell owns the issue across plugin and DSH releases: repeated
|
|
124
|
+
failures update it, a regression reopens it, and a later compatible isolated
|
|
125
|
+
run comments with fresh evidence and closes it. `unknown` is deliberately not
|
|
126
|
+
an accusation against a plugin; it fails the observer lane and waits for a
|
|
127
|
+
trustworthy rerun instead of opening an incident.
|
|
128
|
+
|
|
129
|
+
## Safety boundary
|
|
130
|
+
|
|
131
|
+
| Radar does | Radar does not claim |
|
|
239
132
|
| --- | --- |
|
|
240
|
-
|
|
|
241
|
-
|
|
|
242
|
-
|
|
|
243
|
-
|
|
|
244
|
-
| Check DSH bundle/profile compatibility without business actions | “Compatible” means the plugin is secure |
|
|
245
|
-
| Monitor old → new upstream observations | An LLM can repair evidence that was never collected |
|
|
133
|
+
| Static graph and artifact checks without importing plugin code | An empty finding list proves safety |
|
|
134
|
+
| Dynamic checks in a fresh VM and restricted, secret-free container | A shared-kernel container proves hostile code is harmless |
|
|
135
|
+
| Exact-version advisory matching and dependency paths | Every matched plugin is exploitable |
|
|
136
|
+
| Exact-pair compatibility results with explicit coverage | One successful load covers every plugin business action |
|
|
246
137
|
|
|
247
|
-
|
|
138
|
+
An external symlink in a DSH profile never expands static read scope. Radar only
|
|
139
|
+
uses an outside host plane after it has been discovered from the verified DSH
|
|
140
|
+
process that is actually running the profile.
|
|
248
141
|
|
|
249
|
-
|
|
250
|
-
pnpm add upstream-radar
|
|
142
|
+
## Use it in DSH or CI
|
|
251
143
|
|
|
252
|
-
|
|
253
|
-
|
|
144
|
+
```bash
|
|
145
|
+
# Generate a reviewable DSH inventory and wiring
|
|
146
|
+
npx --yes upstream-radar@0.41.0 setup
|
|
254
147
|
```
|
|
255
148
|
|
|
256
|
-
|
|
149
|
+
The repository also ships a [reusable GitHub Action](action.yml), maintained
|
|
150
|
+
[observer workflow](.github/workflows/upstream-observer.yml), and machine-readable
|
|
151
|
+
[schemas](schemas/). See the [Chinese guide](docs/README.zh-CN.md) for complete
|
|
152
|
+
configuration and [architecture notes](docs/architecture.md) for evidence and
|
|
153
|
+
trust boundaries.
|
|
257
154
|
|
|
258
155
|
## Development
|
|
259
156
|
|
|
@@ -263,4 +160,5 @@ pnpm test
|
|
|
263
160
|
pnpm run release:check
|
|
264
161
|
```
|
|
265
162
|
|
|
266
|
-
|
|
163
|
+
Apache-2.0 licensed. Contributions backed by a reproducible DSH plugin case are
|
|
164
|
+
especially welcome.
|
package/dist/src/cli.js
CHANGED
|
@@ -477,7 +477,7 @@ Usage:
|
|
|
477
477
|
upstream-radar profile-check [profile-directory] [--patch <path>] [--report <path>] [--summary] [--json]
|
|
478
478
|
upstream-radar probe dsh-load <package.tgz> [--dsh-version <exact-version>] [--timeout <seconds>] [--keep-profile] [--json]
|
|
479
479
|
upstream-radar probe dsh-matrix <package.tgz> --dsh-version <v1>[,<v2>,...] [--timeout <seconds>] [--keep-profile] [--json]
|
|
480
|
-
upstream-radar probe dsh-install [npm:]<package>@<exact-version> --dsh-version <exact-version> --isolation-provider <github-actions-hosted-runner|firecracker|other> --execute [--allow-build <package>]... [--timeout <seconds>] [--report <report.json>] [--json]
|
|
480
|
+
upstream-radar probe dsh-install [npm:]<package>@<exact-version> --dsh-version <exact-version> [--case-id <stable-label>] --isolation-provider <github-actions-hosted-runner|firecracker|other> --execute [--allow-build <package>]... [--timeout <seconds>] [--report <report.json>] [--json]
|
|
481
481
|
upstream-radar review dsh-plugin [npm:]<package>@<exact-version> --dsh-version <v1>,<v2>,... [--json]
|
|
482
482
|
upstream-radar demo [--json]
|
|
483
483
|
upstream-radar case dsh-web-ui [--json]
|
|
@@ -1284,6 +1284,7 @@ async function runDshInstallObservation(args) {
|
|
|
1284
1284
|
throw new Error('probe dsh-install requires an exact npm package');
|
|
1285
1285
|
}
|
|
1286
1286
|
let dshVersion;
|
|
1287
|
+
let caseId;
|
|
1287
1288
|
let isolationProvider;
|
|
1288
1289
|
let timeoutSeconds = 180;
|
|
1289
1290
|
let reportPath;
|
|
@@ -1298,7 +1299,7 @@ async function runDshInstallObservation(args) {
|
|
|
1298
1299
|
else if (argument === '--json') {
|
|
1299
1300
|
json = true;
|
|
1300
1301
|
}
|
|
1301
|
-
else if (argument === '--dsh-version' || argument === '--isolation-provider' || argument === '--allow-build' || argument === '--timeout' || argument === '--report') {
|
|
1302
|
+
else if (argument === '--dsh-version' || argument === '--case-id' || argument === '--isolation-provider' || argument === '--allow-build' || argument === '--timeout' || argument === '--report') {
|
|
1302
1303
|
const value = args[index + 1];
|
|
1303
1304
|
if (value === undefined || value.startsWith('-'))
|
|
1304
1305
|
throw new Error(`${argument} requires a value`);
|
|
@@ -1307,6 +1308,13 @@ async function runDshInstallObservation(args) {
|
|
|
1307
1308
|
throw new Error('probe dsh-install accepts only one --dsh-version');
|
|
1308
1309
|
dshVersion = value;
|
|
1309
1310
|
}
|
|
1311
|
+
else if (argument === '--case-id') {
|
|
1312
|
+
if (caseId !== undefined)
|
|
1313
|
+
throw new Error('probe dsh-install accepts only one --case-id');
|
|
1314
|
+
if (!/^[a-z0-9][a-z0-9._-]{0,63}$/.test(value))
|
|
1315
|
+
throw new Error('--case-id must be a short lowercase label');
|
|
1316
|
+
caseId = value;
|
|
1317
|
+
}
|
|
1310
1318
|
else if (argument === '--isolation-provider') {
|
|
1311
1319
|
if (value !== 'github-actions-hosted-runner' && value !== 'firecracker' && value !== 'other') {
|
|
1312
1320
|
throw new Error('--isolation-provider must be github-actions-hosted-runner, firecracker or other');
|
|
@@ -1344,6 +1352,7 @@ async function runDshInstallObservation(args) {
|
|
|
1344
1352
|
const report = await observeDshPluginInstall({
|
|
1345
1353
|
packageSpec,
|
|
1346
1354
|
dshVersion,
|
|
1355
|
+
...(caseId === undefined ? {} : { caseId }),
|
|
1347
1356
|
allowExecution: true,
|
|
1348
1357
|
isolationProvider,
|
|
1349
1358
|
allowedBuilds,
|