dsh-deeppilot 0.9.11 → 0.9.14

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.
@@ -1,9 +1,291 @@
1
1
  # DSH release compatibility memory
2
2
 
3
- > This is the durable audit record for DeepPilot's public DSH plugin. Re-audit
4
- > the next DSH release instead of assuming that an rc upgrade is runtime-safe.
5
-
6
- ## Current decision — `dsh-v0.2.1-rc.3`
3
+ > This is the durable audit record for DeepPilot's public DSH plugin. Since
4
+ > 2026-10-30 the declaration is a rolling range: audit a release when it would
5
+ > move the lower bound, at each `0.x` minor boundary, or when a host inside the
6
+ > range breaks at runtime.
7
+
8
+ ## Audit record — `dsh-v0.2.2-rc.1` (rebuild of alpha.3, no runtime change)
9
+
10
+ - **Release (2026-11-04):** `dsh-v0.2.2-rc.1`, now npm `next`; `latest` stays
11
+ `0.2.1-rc.5`, `alpha` stays `0.2.2-alpha.3`. Inside the rolling range, so **no
12
+ declaration change**. The release notes summarize everything since
13
+ `0.2.1-rc.5`, so most listed items already shipped in `0.2.2-alpha.2/3`.
14
+ - **Tree vs `0.2.2-alpha.3`:** 330 shared packages, zero manifest structural
15
+ changes after normalizing version strings, and only four non-manifest files
16
+ differ (`dsh-client-modules` build commit, three client bundles' version
17
+ strings). `cordis 4.0.6-alpha.2 → 4.1.0` and `schemastery 3.18.6-alpha.2 →
18
+ 3.19.0` change only `package.json` (version and `cosmokit`/`cordis-plugin-*`
19
+ ranges); code is byte-identical. The evaluator `dsh-app-boot/lib/index.js` is
20
+ byte-identical (sha256 `346f8322…`), so every alpha.3 finding — including the
21
+ schedule host-adapter requirement — carries over unchanged.
22
+ - **Gate (real rc.1 evaluator):** worktree `0.9.14` accepted on `0.2.2-rc.1`,
23
+ `0.2.2-alpha.3`, `0.2.1-rc.5`, `0.2.2`; refused on `0.3.0-rc.1`. Published
24
+ `0.9.13` (eight-release list) is refused on every one of them — `next`-channel
25
+ users need `0.9.14` published before the plugin activates.
26
+ - **Boot:** isolated `DSH_HOME` with the rc.1 CLI: `--dump-config` exit 0, empty
27
+ stderr, 7 `deeppilot` hits; `/phone/health` 200 (`protocolVersion` 2,
28
+ `serverVersion` 0.9.14, `dataPlane` active); `deeppilot/host-id` and
29
+ `lan-tls/` created.
30
+ - **Vendor peers (install-time only), decided 2026-11-05:** the previous
31
+ `@deepseek-ai/cordis` / `@deepseek-ai/schemastery` peers did not admit the
32
+ vendored `4.1.0` / `3.19.0`. Both are optional peers the evaluator ignores
33
+ (`engines.dsh` decides), so activation was never affected. `0.9.14` appends
34
+ `~4.1.0` / `~3.19.0` (append, not replace: earlier hosts still vendor the
35
+ older pairs); `tests/compatibility-metadata.test.ts` pins both.
36
+ - **Not covered:** no real-device pairing, Funnel end-to-end, model turn, or
37
+ `npm install` from the registry via the host's plugin manager.
38
+
39
+ ## Audit record — `dsh-v0.2.2-alpha.3` (runtime break inside the range)
40
+
41
+ - **Release (2026-11-03):** `dsh-v0.2.2-alpha.3` on the npm `alpha` channel
42
+ (published 2026-11-03T07:48:26Z); `latest` and `next` remain `0.2.1-rc.5`. It
43
+ is inside the rolling range, so **no declaration change** was needed. The real
44
+ `0.2.2-alpha.3` evaluator accepted the worktree `0.9.14` manifest with zero
45
+ requirements and refused the published `0.9.13` (eight-release list) with a
46
+ single `engines.dsh` requirement — alpha-channel users must upgrade the plugin
47
+ before it activates.
48
+ - **Gate and install surface:** 18 candidate versions were scored with the
49
+ published evaluator and an independent semver recomputation with zero
50
+ disagreements (`0.3.0-0`, `0.3.0-rc.1`, `0.3.0`, `1.0.0` stay refused). The
51
+ host vendors `cordis 4.0.6-alpha.2` / `schemastery 3.18.6-alpha.2`, both
52
+ inside this plugin's peer ranges; its `engines.node` is `>=24.9.0`.
53
+ - **One runtime break, confined to schedule.** `0.2.2-alpha.3` moved automation
54
+ to host-level task management and rewrote `dsh-schedule`: `update` and
55
+ `delete` are gone (`edit({ id, action: 'update' | 'delete', patch,
56
+ expectedUpdatedAt })` replaces them), `list` returns
57
+ `{ items, shown, total, limit, offset }` instead of an array, `create` takes
58
+ `(request, actorSessionId, signal)`, and the request body uses `timing` /
59
+ `target` instead of `at` / `after_seconds` / …. The four bridge call sites
60
+ (`src/dsh-api-proxy.ts:216/232/236/248`) still speak the `0.2.2-alpha.2`
61
+ contract, so the phone's schedule list, create, edit and delete fail while
62
+ `schedule.history` keeps working. The `schedules` capability bit stays `true`
63
+ because it probes service presence only, so the break is silent (each action
64
+ returns an internal error) instead of hiding the feature. No other contract
65
+ changed: 24 of the 25 audited interfaces are identical or compatibly changed
66
+ and the client face is untouched.
67
+ - **Runtime verification:** an isolated `0.2.2-alpha.3` host composed and started
68
+ the `0.9.14` worktree (`--dump-config` exit 0, no skipped bundle, 199 composed
69
+ entries), `/phone/health` returned 200 with `protocolVersion` 2 and
70
+ `serverVersion` `0.9.14`, and the live 3080 host on the same build serves the
71
+ same plugin from its linked worktree. The config schema projection accepts
72
+ every `deeppilot` option, and `NODE_DEBUG=esm` proves the plugin's
73
+ `@deepseek-ai/*` imports resolve to the alpha.3 installation tree rather than
74
+ the pinned dev copies.
75
+ - **Decision:** keep the rolling range; ship `0.9.14` so alpha-channel users get
76
+ a host-activatable plugin. The schedule adapter now serves both contracts
77
+ (shape-detected `legacy` / `host` adapters, additive protocol v2 capability
78
+ `schedulesHost`, host-level frames, legacy frames projected onto host-level
79
+ tasks, iOS mirror); the wire contract lives in `PROTOCOL.md` section "Schedule
80
+ 宿主级任务扩展". The public contract consequence is recorded in
81
+ `COMPATIBILITY.md`.
82
+ - **Evidence:** `.alpha3-verify/AUDIT.md`, `CHANGE_SURFACE.md`, `CLIENT_FACE.md`,
83
+ `HOST-BOOT.md` and `logs/` in this repository; `.alpha3-verify/gate-matrix.mjs`
84
+ reproduces every activation verdict.
85
+
86
+ ## Current decision — rolling range from `dsh-v0.2.1-rc.5`
87
+
88
+ - **Decision (2026-10-30):** the compatibility declaration is one rolling range,
89
+ `>=0.2.1-rc.5 <0.3.0-0`, in `engines.dsh` and all ten `@deepseek-ai/dsh*`
90
+ peers, replacing the eight-release closed list. The lower bound is the newest
91
+ `rc` release (`0.2.1-rc.5`, published 2026-10-29T14:15:23Z); the current
92
+ `alpha` release `0.2.2-alpha.2` sorts above it and needs no second clause.
93
+ `<0.3.0-0` keeps the `0.3.0` audit gate. Dev packages move to the exact
94
+ `0.2.1-rc.5` baseline with vendored `cordis 4.0.5` / `schemastery 3.18.5`.
95
+ Release `0.9.14`. Recorded in `docs/adr/0001-dsh-compatibility-policy.md`
96
+ section 8.
97
+ - **Trigger:** `latest` and `next` both moved to `0.2.1-rc.5`; the closed list
98
+ (ending `0.2.2-alpha.2`) refused to activate on it, and every DSH release
99
+ required eleven declaration edits plus a lockfile, test, and doc pass.
100
+ - **Audit of `dsh-v0.2.1-rc.5` against `dsh-v0.2.1-rc.4` (`.rc5-verify/`):**
101
+ **no runtime break, `src/` unchanged.** 307 = 307 packages; 42,731 shared
102
+ files: 42,421 byte-identical, 310 differing (296 `package.json` + 14
103
+ non-manifest files in 7 packages), plus one file new in rc.5 only
104
+ (`dsh-client-ui-chat/lib/types/client/reasoning-text.d.ts`, 363 B). The rc.4
105
+ tree fingerprint reproduced the previous audit's value. All 307 manifests have
106
+ zero structural changes across the full 11,099-leaf union; 3,706 dependency
107
+ specs are mechanical `0.2.1-rc.4 → 0.2.1-rc.5` replacements. The evaluator
108
+ `dsh-app-boot/lib/index.js` is byte-identical to rc.4 (sha256 `5135179a…`,
109
+ same as rc.3). `dsh-web-app/cordis.patch.yml` is byte-identical, so the
110
+ `id: directory-picker` patch anchor is untouched. The four client faces are
111
+ byte-identical. 3,271 `lib/` modules and 681 entry modules show zero export
112
+ deltas. The 15 non-manifest files (14 changed, 1 added) live in
113
+ `dsh-client-ui-chat` (the internal `conversation.chat.reasoning.body` Slot
114
+ gains `rawText`, reasoning text strips its `<signature>` wrapper before
115
+ display, plus types and READMEs), `dsh-cordis-client-runner` (embedded Slot
116
+ registry metadata), `dsh-experimental-client-ui-cot-translation` (JSDoc/type
117
+ comments only), `dsh-client-modules` (build-commit constant), and three
118
+ settings/sidebar client bundles (version strings, same byte size). A machine
119
+ check over the 7 packages reports `allOutsideDeclarationSurface`; none is in
120
+ the declaration surface (10 peers + 4 client injects + vendored
121
+ cordis/schemastery) or the plugin call surface.
122
+ - **Matrix (rc.5 evaluator, `includePrerelease: true`):** before → `0.2.1-rc.5`
123
+ rejected; after → `0.2.1-rc.5`, `0.2.2-alpha.2`, `0.2.1`, later rc/alpha/GA
124
+ admitted — 12 candidates newly admitted, exactly the seven former list members
125
+ newly refused — while `0.3.0-rc.1`, `0.3.0`, `0.3.0-0`, and `1.0.0` stay
126
+ rejected. Every verdict matched an independent semver calculation, and dropping
127
+ `engines.dsh` to exercise the peer path yields the same accepted set. The range
128
+ also admits unaudited prereleases above the bound by construction
129
+ (`0.2.2-alpha.1`, `0.2.2-alpha.2.1`, `0.2.2-ALPHA.2`, `0.2.2-0`); this is
130
+ pinned as a known admission surface in `tests/compatibility-metadata.test.ts`.
131
+ - **Positive load (isolated `DSH_HOME`, `.rc5-verify/HOST-BOOT.md`):** with a
132
+ projected manifest carrying only the new range, the rc.5 host composes the
133
+ plugin (`--dump-config` exit 0, no `skipping profile bundle` line, 7
134
+ `deeppilot` hits), starts it, and the plugin's own LAN port answers
135
+ `/phone/health` with 200 (`ok`, `enabled`, `protocolVersion` 2, `dataPlane`
136
+ active). Both the committed 0.9.13 artifacts (`serverVersion` 0.9.13) and the
137
+ in-flight 0.9.14 worktree (`serverVersion` 0.9.14) load. The isolated home
138
+ received `deeppilot/host-id` and `deeppilot/lan-tls/`.
139
+ - **Verification:** `npm test` 681 (679 pass, 1 pre-existing todo, 1 skipped),
140
+ `typecheck`, `build`, `check:config-schema` against the `0.2.1-rc.5` CLI,
141
+ `smoke:helper`, `go test ./...`, `bin/SHA256SUMS` 6/6.
142
+ - **Evidence:** `.rc5-verify/AUDIT.md`, `CHANGE_SURFACE.md`, `HOST-BOOT.md`,
143
+ `tree-compare.out.json`, `matrix.out.json`, `evaluator-repro.out.json`,
144
+ `patch-anchor-check.out.json`, `export-symbol-diff.out.json`,
145
+ `pkg-manifest-delta.out.json`, `vendor-check.out.json`, `diffs/`, `logs/`.
146
+ - **Honest boundary:** `dsh-client-ui-slots` has no artifact in either tree (as
147
+ in the rc.4 round), so it was not byte-compared; `react` and the npm
148
+ install-time resolution were not checked; no real-device pairing, Funnel
149
+ end-to-end, or model turn was run; `0.9.14` is prepared locally, not
150
+ published.
151
+
152
+ ## Current decision — `dsh-v0.2.2-alpha.2`
153
+
154
+ - **Audited release:** `dsh-v0.2.2-alpha.2`, published to the npm registry
155
+ 2026-10-28T02:50:54Z (GitHub Release 2026-10-28T02:50:54Z), and the **`alpha`**
156
+ channel release — `alpha` moved from `0.2.1-alpha.5` to it. It is **not**
157
+ `latest` (still `0.2.1-rc.2`) and not `next` (`0.2.1-rc.4`, audited below in the
158
+ same pass). This is the first `0.2.2` line release to enter the supported list,
159
+ and the first one to carry a real runtime break since `0.2.1-alpha.3`.
160
+ - **Comparison baseline:** `dsh-v0.2.1-rc.3` (the previous audited tag).
161
+ - **Plugin runtime verdict: one break, confined to the history read; fixed in
162
+ `src/dsh-api-proxy.ts`.** The tree grows 307 → 332 packages (26 added, 1
163
+ dropped). `@deepseek-ai/dsh-api-session-controller` removed
164
+ `SessionController.inspect(sessionId, signal?)` — absent from
165
+ `lib/types/index.d.ts` and from the runtime `lib/index.js` (the rc.3
166
+ `inspectApiSession` helper and the class method are both gone). This plugin's
167
+ `sessions.history` read a whole log through it, so on this host the phone's
168
+ history pagination threw `TypeError`; pairing, listing, prompting, the settings
169
+ page, and the plugin page all kept working, and the phone protocol itself is
170
+ unchanged because `HistoryResult` has the same shape.
171
+ - **The fix branches on `inspect`, not on `page`.** `page(request, signal)` exists
172
+ on all eight admitted hosts with an identical signature and a stable
173
+ `{records, hasMore}` result, but `SessionPageRequest.throughSeq` is **mandatory
174
+ and validated** on the seven older ones and this adapter has no log cursor to
175
+ pass, so a unified `page` path would have broken every host below
176
+ `0.2.2-alpha.2`. The adapter keeps `inspect` when present, and otherwise reads
177
+ `page` with the phone's exclusive `beforeSeq` expressed as the inclusive
178
+ `throughSeq` (`beforeSeq - 1`; `-1` is the host's empty page) and unwraps the
179
+ host's `{type:'event',event}` records to the bridge's `{event}` contract.
180
+ `host-bridge.ts` already re-checks the seq boundary, so the inclusive cut
181
+ cannot make a client loop on one page.
182
+ - **No other export change reaches the plugin.** 24 packages / 358 modules were
183
+ compared; 20 modules changed export surfaces but only two at entry level
184
+ (`dsh-api-session-controller` dropping `buildModelCatalog`; `dsh-app-boot`
185
+ dropping `DEFAULT_PROFILE_BUNDLES`, `OFFICIAL_ON_DEMAND_CATALOG`,
186
+ `ON_DEMAND_BUNDLES`, `OPTIONAL_BUNDLES`, `PROFILE_TEMPLATES` and adding three
187
+ platform helpers). A repo-wide grep shows the plugin uses none of them; the
188
+ three packages it actually imports (`cordis`, `dsh-typert-protocol`,
189
+ `schemastery`) have unchanged export surfaces. Two earlier script findings —
190
+ `connection` missing `createPeer` / `createSharedFetchHandler` and `typert`
191
+ missing `register` — were false positives from reading `rpc-host.d.ts` instead
192
+ of `rpc.d.ts`, and from comparing against a symbol neither version has; both are
193
+ recorded as corrections in `.alpha2-verify/AUDIT.md`.
194
+ - **Patch anchor still valid.** The upstream `dsh-web-app/cordis.patch.yml`
195
+ changed 3 ids in and 3 out; the block this plugin disables
196
+ (`directory-picker`) moved from line 113 to 105 and byte 4664 to 4309, but the
197
+ block bytes and sha256 are identical, the shared id order is unchanged, and both
198
+ hosts' `loadOverlayPatches` resolve this plugin's patch to the same fields.
199
+ - **Vendor peers: appended, not substituted.** This host vendors
200
+ `cordis 4.0.6-alpha.1` and `schemastery 3.18.6-alpha.1`, which the previous
201
+ ranges did not admit under npm's default prerelease rule (they did under
202
+ `includePrerelease`). The ranges now append `~4.0.6-alpha.1` / `~3.18.6-alpha.1`
203
+ after the GA clauses, because every earlier admitted host still vendors
204
+ `4.0.5` / `3.18.5`; replacing instead of appending would have been a
205
+ narrowing. DSH's evaluator ignores both peers (a manifest carrying only these
206
+ two passes), so this is an install-time and documentation concern. The
207
+ `cordis 4.0.5 → 4.0.6-alpha.1` diff is a pure refactor (`_resolveConfig` →
208
+ public `resolveConfig`, new `rawConfig`/`effectiveConfig`, `this.` →
209
+ `this.ctx.fiber.`) with an unchanged 26-symbol export surface;
210
+ `schemastery` changed only `package.json`.
211
+ - **Activation verdict: the new release is admitted by both declarations.**
212
+ Before the widening, this host refused the plugin with a **single**
213
+ `engines.dsh` requirement and `exempted: false`, skipping the whole bundle.
214
+ After it, `afterNewlyAccepted = ["0.2.2-alpha.2"]` and
215
+ `afterNewlyRejected = []`; `0.2.2-alpha.1`, `0.2.2-alpha.2.1`,
216
+ `0.2.2-alpha.20`, `0.2.2-ALPHA.2`, `0.2.2-rc.1`, `0.2.2`, `0.2.1`,
217
+ `0.2.3`, and `1.0.0` stay refused. The projection is append-only: every other
218
+ manifest field is untouched.
219
+ - **Evidence.** `.alpha2-verify/AUDIT.md` and `CHANGE_SURFACE.md`, with 12
220
+ re-runnable scripts (`tree-compare`, `export-symbol-diff`, `call-surface-check`,
221
+ `history-api-matrix`, `vendor-range-check`, `evaluator-repro`, `matrix`,
222
+ `patch-anchor-check`, `client-face-check`, `pkg-manifest-delta`,
223
+ `snapshot-state.sh`, `surface-evidence.sh`), 12 `*.out.json` results, 180
224
+ diffs, and 30+ raw logs. The history-API matrix
225
+ (`.alpha2-verify/history-api-matrix.out.json`) is what proves the branch
226
+ decision: `inspect` present on 7/8 hosts, `page` present on 8/8,
227
+ `SessionPage` shape stable on 8/8.
228
+ - **Not covered / limits.** No real iPhone run and no Funnel end-to-end. No live
229
+ host boot on `0.2.2-alpha.2` was performed for this entry (the isolated-host
230
+ boot is tracked separately below). `dsh-client-ui-slots` was not tarball-compared
231
+ because this machine has no outbound HTTPS for `npm pack`; the plugin never
232
+ imports or injects that package and its `slots` service comes from
233
+ `dsh-client-ui-renderer`, which changed only `package.json`. npm install-time
234
+ peer resolution was not exercised.
235
+ - **Install-side prerequisite.** This host's `dsh` package raised
236
+ `engines.node` to `>= 24.9.0` — the only structural `package.json` change among
237
+ the 19 declared peers. The plugin's own `engines.node` stays `>=22`; a `0.2.2`
238
+ host simply cannot run on Node below 24.9.
239
+
240
+ ### Three optional capabilities verified in the same pass (2026-10-29)
241
+
242
+ - **alpha.2 isolated host:** 32/32 checks, including `assistantStream`,
243
+ `sessionMarkdown` and `pluginUpdate` all advertised. A synthetic turn produced
244
+ `stream.start` → `message.delta` → matching `message.final` (`data.streamId`)
245
+ → committed `stream.end`; Markdown export returned 10 chunks / 484,669 bytes
246
+ with `text/markdown; charset=utf-8`; update `check` answered without ever
247
+ sending `apply`.
248
+ - **rc.4 isolated host:** 27/27 checks. `assistantStream=true`, while
249
+ `sessionMarkdown` and `pluginUpdate` correctly stay false: rc.4's
250
+ `dsh-session-log-export` has no `session.markdown` route and its
251
+ `dsh-plugin-manager` exposes neither `listVersions` nor `updateBundle`.
252
+ The old ZIP path and old-client behaviour are unchanged.
253
+ - **Automated:** plugin `npm test` 679 tests (677 pass, 1 intentional TODO,
254
+ 1 env-gated real-host comparison; the comparison passes 21/21 with
255
+ `DSH_ALPHA2_PLUGIN_MANAGER` set). iOS offline suite 513 tests, 0 failures,
256
+ 2 skips. Both committed trees build.
257
+ - **Not covered:** no real iPhone, no system share sheet, no real npm install
258
+ through `updateBundle`/HMR rollback, no Funnel. Those remain manual gates.
259
+
260
+ ### `dsh-v0.2.1-rc.4`, audited in the same pass
261
+
262
+ - **Audited release:** `dsh-v0.2.1-rc.4`, published 2026-10-28T02:49:58Z, the
263
+ **`next`** channel release (`next` moved from `0.2.1-rc.3`). Baseline:
264
+ `0.2.1-rc.3`.
265
+ - **Verdict: no change that reaches this plugin, no `src/` change.** 307 packages
266
+ on both sides; 42,415 of 42,731 shared files byte-identical; 316 differing paths
267
+ = 296 `package.json` + 20 files in eight packages (`dsh-mcp-client` capability
268
+ gating for `resources/list`, `dsh-llm-deepseek-account` moving one log call to
269
+ stderr, `dsh-client-ui-conversation` View tooltip plus one removed locale key,
270
+ four version/build strings, and documentation). None is in the plugin's
271
+ declaration or call surface. `package.json` structural changes: 0 across all
272
+ 307 packages; 3,706 dependency-spec changes are mechanical `rc.3 → rc.4`
273
+ substitutions. Export surfaces: 0 changes across 3,271 `lib/` modules and 681
274
+ entry modules. The evaluator is the same file as rc.3 (same sha256).
275
+ - **Patch anchor:** `dsh-web-app/cordis.patch.yml` is byte-identical to rc.3;
276
+ the `directory-picker` anchor keeps line 113, byte 4664, and the same block
277
+ sha256.
278
+ - **Activation:** before the widening this host refused the plugin (single
279
+ `engines.dsh` requirement); after it, exactly `0.2.1-rc.4` is newly accepted,
280
+ nothing is newly rejected, and `0.2.1-rc.5`, `0.2.1`, `0.2.1-rc.4.1`,
281
+ `0.2.1-rc.40`, `0.2.1-RC.4`, and `0.2.1-rc.10` stay refused. Vendor pair is
282
+ still `cordis 4.0.5` / `schemastery 3.18.5`, both byte-identical to rc.3.
283
+ - **Evidence:** `.rc4-verify/AUDIT.md`, `CHANGE_SURFACE.md`, 10 scripts, 9
284
+ `*.out.json` results, 316 diffs. The comparator carries a negative control (a
285
+ byte-identical package compared against itself yields 0 differences; the same
286
+ package with one bit flipped yields exactly 1).
287
+
288
+ ### Previous decision — `dsh-v0.2.1-rc.3`
7
289
 
8
290
  - **Audited release:** `dsh-v0.2.1-rc.3`, published to the npm registry
9
291
  2026-10-23T07:54:30Z (GitHub Release 2026-10-23T15:26:39Z), and the **`next`**
@@ -85,8 +367,20 @@
85
367
  default npm cache on this machine holds root-owned files, so the
86
368
  `check:config-schema` script's `npx` invocation fails with `EPERM` until
87
369
  `npm_config_cache` points at a writable directory; with that variable set the
88
- check passes. No `npm ci`, no commit, no push, no tag, and no npm publish: the
89
- release is prepared but not shipped.
370
+ check passes.
371
+ - **Shipped as `dsh-deeppilot@0.9.11`.** Release commit
372
+ `a12750c84f1c2ecd579f87f3b5d60507fa3a7112`, annotated tag `v0.9.11`; CI
373
+ (`40055850654`) and CodeQL (`40055850739`) are green, and `publish.yml` run
374
+ `40056208123` completed all 24 steps — including the final version, integrity
375
+ and provenance check that several earlier releases failed on. Registry reads
376
+ `latest = 0.9.11`, 68 entries, 131,040,038 unpacked bytes, and SLSA provenance
377
+ of type `https://slsa.dev/provenance/v1` whose `gitCommit` is that release
378
+ commit at `refs/tags/v0.9.11`. The tarball answered `HTTP 404` for roughly
379
+ three minutes after publication, so an install check needs retries. A clean
380
+ isolated `DSH_HOME` then installed the published package **from npm** (not from
381
+ the working tree) and a real `0.2.1-rc.3` host loaded it and answered
382
+ `/phone/health` with 200 and `serverVersion: "0.9.11"`; the GitHub Release was
383
+ made public and marked Latest only after that check.
90
384
  - **Not covered / limits.** No real iPhone run, no Funnel end-to-end, no
91
385
  model-backed turn against this host. `npm ci` and the helper-matrix rebuild
92
386
  steps were skipped because no helper, dependency, or source input changed; CI
@@ -171,7 +465,7 @@
171
465
  0.2.1-alpha.3 || 0.2.1-alpha.4 || 0.2.1-alpha.5 || 0.2.1-rc.2`, mirrored in
172
466
  `tests/compatibility-metadata.test.ts`, `package-lock.json` (root entry only),
173
467
  both READMEs, `COMPATIBILITY.md`, `AGENTS.md`, and the local
174
- `docs/决策记录.md` (章节一, 条目5). The tests now also pin `0.2.1-rc.1` and
468
+ `docs/adr/0001-dsh-compatibility-policy.md` (item 5). The tests now also pin `0.2.1-rc.1` and
175
469
  `0.2.1-rc.3` as negative probes, so neither the skipped rc nor the next rc can be
176
470
  admitted by accident. The dev pins and `DSH_BASELINE` stay at the exact
177
471
  `0.2.0-rc.2` this branch builds and typechecks against.
@@ -296,7 +590,7 @@
296
590
  0.2.1-alpha.3 || 0.2.1-alpha.4 || 0.2.1-alpha.5`, mirrored in
297
591
  `tests/compatibility-metadata.test.ts`, `package-lock.json` (root entry only),
298
592
  both READMEs, `COMPATIBILITY.md`, `AGENTS.md`, and the local
299
- `docs/决策记录.md` (章节一, 条目4). The dev pins and `DSH_BASELINE` stay at the
593
+ `docs/adr/0001-dsh-compatibility-policy.md` (item 4). The dev pins and `DSH_BASELINE` stay at the
300
594
  exact `0.2.0-rc.2` this branch builds and typechecks against.
301
595
  - **Protocol verdict: no phone-protocol change.** Protocol v2, pairing state, and
302
596
  device records are untouched by this release; no phone needs to re-pair.
@@ -381,8 +675,8 @@
381
675
  `engines.dsh` and all ten `@deepseek-ai/dsh*` peers named `0.2.0-rc.2 ||
382
676
  0.2.1-alpha.3 || 0.2.1-alpha.4`, mirrored in
383
677
  `tests/compatibility-metadata.test.ts`, `package-lock.json`, both
384
- READMEs, `COMPATIBILITY.md`, `AGENTS.md`, and the local `docs/决策记录.md`
385
- (章节一, 条目3). The dev pins and `DSH_BASELINE` stay at the exact
678
+ READMEs, `COMPATIBILITY.md`, `AGENTS.md`, and the local `docs/adr/0001-dsh-compatibility-policy.md`
679
+ (item 3). The dev pins and `DSH_BASELINE` stay at the exact
386
680
  `0.2.0-rc.2` this branch builds and typechecks against. **Historical note:**
387
681
  `0.2.1-alpha.5` was appended to both lists on 2026-10-16 by the audit above,
388
682
  which now owns the current list; the four documentation mirrors that still
@@ -450,8 +744,8 @@
450
744
  across all ten `@deepseek-ai/dsh*` peers, and the two vendor peers widened to
451
745
  `~4.0.4 || ~4.0.5-alpha.1` and `~3.18.4 || ~3.18.5-alpha.1`. Because DSH
452
746
  evaluates that range on every start, the next DSH release deactivates this
453
- plugin until the list is widened deliberately — see `docs/决策记录.md`
454
- (章节一, 条目2), which records this as a reversal of the 2026-09-29 policy.
747
+ plugin until the list is widened deliberately — see `docs/adr/0001-dsh-compatibility-policy.md`
748
+ (item 2), which records this as a reversal of the 2026-09-29 policy.
455
749
  The published CLI composed the plugin's patch cleanly before the change (see
456
750
  the 2026-10-14 entry). The plugin's own `lib/client.js` shape was not
457
751
  re-verified against the alpha.3 client-modules scanner.
@@ -703,7 +997,7 @@
703
997
  page instead of gating installability on it. The re-audit obligation below
704
998
  is unchanged: still source-diff and record every new DSH release; a `0.3.x`
705
999
  line still requires its own audit and its own range widening before it
706
- installs. Recorded in `docs/决策记录.md` (章节一, 条目1).
1000
+ installs. Recorded in `docs/adr/0001-dsh-compatibility-policy.md` (item 1).
707
1001
  - **Install/deployment verdict:** the peer range, the compatibility assertions,
708
1002
  the registry lockfile, and generated `lib/` are updated for rc.2. `npm ci`,
709
1003
  unit tests (304 passing), typecheck, build, the config-schema check against a
@@ -722,6 +1016,135 @@
722
1016
  bundle" below. The plugin needs no code change; the phone's copy now points
723
1017
  at the bundle.
724
1018
 
1019
+ ## 2026-10-24 — 插件链路实测:`dsh-v0.2.1-rc.3` 上的运行中排队与转向
1020
+
1021
+ 这不是版本审计:没有放行或下线任何版本。本节验证插件尚未提交的「运行中排队与转向」实现
1022
+ (`promptQueue` 能力,见 `PROTOCOL.md`「运行中排队与转向扩展」),在真实宿主上能否按协议
1023
+ 完整跑通:从手机帧,经 Bridge,到 Host 的 `prompt` / `updateQueue` 与 `inbox` 投影,再回到
1024
+ 手机。
1025
+
1026
+ ### 方法
1027
+
1028
+ - 宿主 CLI:npx 缓存中的 `0.2.1-rc.3` 安装(`dsh --version` 输出 `0.2.1-rc.3`)。
1029
+ - 插件:当前工作副本构建后用 `npm pack` 打成本地包,经
1030
+ `dsh plugin --profile queue add <tgz>` 装入。装好后确认包内 `lib/index.js` 带有
1031
+ `promptQueue`。
1032
+ - 隔离 `DSH_HOME` 放在一次性临时目录(已删除),profile 用 `--from-default-profile web`
1033
+ 创建。设备身份用 `scripts/smoke-live.mts register` 预先写入 `devices-v2.json`。连接走真实
1034
+ 的 TLS 与签名挑战握手,不经过配对码。
1035
+ - 额外挂载一个补丁,引入仅供测试的夹具,并用显式环境变量把关:本机 OpenAI 兼容模型,监听
1036
+ `127.0.0.1:3388`,每个请求延迟 15 秒才回复。夹具只记录合成会话里用户消息的文本,用来核对
1037
+ 转向插进了哪一轮。
1038
+ - 测试客户端是临时脚本,每 15 秒发一次 `c2s.ping`,按清单逐项断言。宿主 Web 端口 3387,
1039
+ 插件手机端 3398。结束后停掉宿主,确认三个端口都已无监听。
1040
+
1041
+ ### 结果
1042
+
1043
+ | 检查项 | 实际看到的 | 结论 |
1044
+ | --- | --- | --- |
1045
+ | 能力声明 | `welcome.capabilities.promptQueue=true` | 通过 |
1046
+ | 打开会话 | 先收到 `s2c.session.tail`,再收到一帧空快照,这帧不带 seq | 通过 |
1047
+ | 运行中排队 | 乙、丙依次进入 `queued`,各带自己的 `clientSendId`,帧带 seq | 通过 |
1048
+ | 同 ID 重发 | 回执复用(`accepted`、原 `userSeq`),队列没有多出一项 | 通过 |
1049
+ | 转向 | 收到 ack 后快照分两帧:先是丙离开,再是丙以 `steering` 出现 | 通过 |
1050
+ | 删除 | ack 后快照里不再有乙;对乙再转向返回 `E_NOT_FOUND` | 通过 |
1051
+ | 转向不可用 | 运行中把戊排进队列,再 `c2s.session.cancel`;取消后戊留在 `queued`,Host 没有自动领取;对戊转向返回 `E_STEER_UNAVAILABLE` | 通过 |
1052
+
1053
+ 模型侧的调用记录与快照一致:
1054
+ - 转向后的丙,作为甲那一轮的第二步发给了模型,没有另起一轮。
1055
+ - 丁单独作为一轮运行。
1056
+ - 戊从未发给模型:取消后它留在排队区,随后被删除。
1057
+
1058
+ ### 发现
1059
+
1060
+ - **空闲会话上发 `mode:"steer"`**:Host 正常受理。该项先在快照里以 `steering` 出现一帧,
1061
+ 随后被领取,按普通的一轮运行,不报错。
1062
+ - **空闲时普通发送也经过排队区**:该项会以 `queued` 短暂出现一帧,下一帧即消失。这在插件
1063
+ 链路上复现了 rc.2 探针的结论,客户端对账时必须容忍这类一闪而过的项。
1064
+ - **`cancel` 不领取排队项**:取消后排队项仍然保留,会话停在空闲,直到有下一次发送或删除。
1065
+ 这让 rc.2 探针里「无法构造」的 `session/steer-unavailable` 空闲场景,有了稳定的构造方法。
1066
+ - **监听地址**:插件手机端监听在 `0.0.0.0:3398`,这是 LAN 传输的固定行为。验收时设备注册表
1067
+ 里只有冒烟设备。
1068
+
1069
+ ### 局限
1070
+
1071
+ - 只跑了 `0.2.1-rc.3`。`0.2.0-rc.2` 上的插件链路没有实测,只有上次的宿主侧探针。
1072
+ - 第一轮运行有两个问题:客户端没发心跳,约 100 秒后被插件断开;部分等待条件匹配到了更早的
1073
+ 帧。修正客户端后,在新会话上重跑才得到上表。第一轮里丁没有出现在历史和模型记录里,当时
1074
+ 没有检查它的发送回执,原因未查清。推测它是在上一轮结束的瞬间发出、被 Host 拒收,但没有
1075
+ 证据。
1076
+ - 只测了单台设备。快照「所有设备相同」与多设备并发操作都没有覆盖。
1077
+ - 模型是合成的,固定输出不代表真实供应商的行为。
1078
+
1079
+ ## 2026-10-24 — 运行时探针:`dsh-v0.2.0-rc.2` 上的 `inbox` 投影
1080
+
1081
+ 这不是版本审计:没有放行或下线任何版本,插件代码也没有改动。本节只回答计划中手机端
1082
+ 「运行中排队与转向」可选能力(`sessionController.updateQueue`,见下文「New rc.2
1083
+ capabilities worth using」)背后唯一悬而未决的问题:最早放行的宿主版本,是否通过本插件
1084
+ 已在使用的投影通道发布待处理收件箱(inbox)。
1085
+
1086
+ ### 静态证据
1087
+
1088
+ - `@deepseek-ai/dsh-agent-loop@0.2.0-rc.2`(`lib/index.js:27`)注册了带对外视图
1089
+ (wire view)的标准 `inbox` 投影。其状态为
1090
+ `{ "next-turn": Message[], "next-step": Message[] }`,由持久事件
1091
+ `agent/inbox/spliced` 折叠而来;折叠会拒绝越界的 splice,以及同时出现在两个列表里的
1092
+ 同一个 `MessageId`。
1093
+ - `@deepseek-ai/dsh-api-session-controller` 的 `0.2.0-rc.2` 与 `0.2.1-rc.3`
1094
+ (registry 包)带有相同的 `updateQueue` 实现:`edit`(只接受非空纯文本)、`remove`
1095
+ (同时释放该提示词的上传附件)、`steer`(只接受 `next-turn` 中的项且 Agent 正在运行,
1096
+ 否则返回 `session/steer-unavailable`)。项不存在时返回 `session/queue-item-not-found`。
1097
+ 两个版本的 README 都说明:提示词的 `requestId` 会持久化为用户来源的 `rpcId`,待处理
1098
+ 收件箱里的消息也保留这一来源。
1099
+ - `0.2.1-rc.3` 在会话列表投影的类型定义里列出了 `inbox`,`0.2.0-rc.2` 没有列出,这正是
1100
+ 需要做运行时探针的原因。
1101
+
1102
+ ### 方法
1103
+
1104
+ - 宿主 CLI:npx 缓存中的 `0.2.0-rc.2` 安装(`dsh --version` 输出 `0.2.0-rc.2`)。
1105
+ - 隔离 `DSH_HOME` 位于一次性临时目录(已删除),profile 用 `--from-default-profile web`
1106
+ 创建。`--dump-config` 退出码 0、stderr 为空、组合树中没有 `deeppilot` 行:刻意不加载
1107
+ 插件。
1108
+ - 额外挂载一个补丁,引入仅供测试的夹具,并用显式环境变量把关:
1109
+ - 本机 OpenAI 兼容模型,监听 `127.0.0.1:3288`,经 `llm-pi-ai` 以占位密钥注册;每个
1110
+ 请求延迟 40 秒才回复,让该轮一直处于运行中;
1111
+ - 订阅 `sessionProjections.onChanged` 的探针,与 `src/dsh-api-proxy.ts` 使用的是同一
1112
+ 接口。只对 `inbox` 键打印两个列表的长度、消息 ID 前 8 位、`source.kind`,以及是否带
1113
+ `source.rpcId`,不打印任何消息正文。夹具必须声明 `inject: ['sessionProjections']`,
1114
+ 否则 `apply` 时取不到该服务。
1115
+ - 在宿主自带的 Web 界面(端口 3287)上操作:发送 A;A 运行期间发送 B 和 C;在排队区对
1116
+ B 转向;删除 C;等 A 结束。结束后停掉宿主,确认 3287 与 3288 端口已无监听。
1117
+
1118
+ ### 结果
1119
+
1120
+ | 检查项 | 探针输出 | 结论 |
1121
+ | --- | --- | --- |
1122
+ | 投影存在且实时推送 | 发出 B、C 后:`next-turn=2`、`next-step=0` | 通过 |
1123
+ | 能对应回发送 | 每一项均为 `kind=user` 且带 `rpcId` | 通过 |
1124
+ | 转向 | 先是 `next-turn=1 [C] next-step=0`,再是 `next-turn=1 [C] next-step=1 [B]` | 通过 |
1125
+ | 删除 | `next-turn=0`、`next-step=1 [B]` | 通过 |
1126
+ | 被领取执行 | A 结束后:`next-step=0`,随后出现一次新的模型请求 | 通过 |
1127
+
1128
+ Web 界面表现一致:排队区标题为「2 条排队消息」,每项带编辑、删除与「插话发送」(转向)
1129
+ 操作,被转向的 B 立即显示在会话尾部。
1130
+
1131
+ ### 对队列能力的影响
1132
+
1133
+ - 转向分两帧完成:B 先离开 `next-turn`,下一帧才进入 `next-step`。客户端必须按
1134
+ `MessageId` 跨两个列表跟踪各项,不能把只缺席一帧当作被删除。
1135
+ - 空闲会话上的提示词也会先经过 `next-turn` 再被领取,因此出现在收件箱里不能作为该轮正在
1136
+ 运行的证据。
1137
+ - 本次探针不要求插件做任何改动。该能力仍是可选能力,以 `updateQueue` 与 `inbox` 投影同时
1138
+ 可用为前提。
1139
+
1140
+ ### 局限
1141
+
1142
+ - 没有运行 `0.2.1-rc.3`;其静态证据与本版一致。
1143
+ - 没有加载插件。探针用的是同一个 `onChanged` 接口,但插件自身的折叠与手机帧仍未测试。
1144
+ - 空闲会话上对排队项转向返回 `session/steer-unavailable` 只有源码证据:空闲会话会立即
1145
+ 领取排队项,这种状态无法构造出来。
1146
+ - 模型是合成的,其固定输出不代表任何真实供应商的行为。
1147
+
725
1148
  ## 2026-10-16 — audit of `dsh-v0.2.1-alpha.5`
726
1149
 
727
1150
  The first release on this line whose entire plugin-facing change surface is
@@ -1065,7 +1488,7 @@ either host. `devDependencies` stay pinned to `0.2.0-rc.2`.
1065
1488
  The consequence is deliberate: `evaluatePluginCompatibility` runs before a
1066
1489
  profile is composed on every start, so the next DSH release will refuse to
1067
1490
  activate this plugin until the list is widened by an audit. That reversal of the
1068
- 2026-09-29 policy is recorded in `docs/决策记录.md` (章节一, 条目2).
1491
+ 2026-09-29 policy is recorded in `docs/adr/0001-dsh-compatibility-policy.md` (item 2).
1069
1492
  `tests/compatibility-metadata.test.ts` now asserts both admissions, fifteen
1070
1493
  rejections, and the two vendor ranges.
1071
1494
 
@@ -1910,3 +2333,13 @@ release notes.
1910
2333
  2. 手机协议:模型当前选择投影新增 `s2c.models.changed`,受 `sessions.read` 控制;原生权限执行可附加 `expectedDefinitionId`,重读目录核对来源,旧客户端字段缺省兼容。无新增周期轮询或第二层主机时间缓存。
1911
2334
  3. 客户端:内存五分钟、磁盘最长七天,重启旧目录先展示并校验,按配对身份/主机/会话隔离;当前模型、权限和执行结果不落盘。具体约定和格式重建见[移动端目录缓存](移动端目录缓存.md)。
1912
2335
  4. 验证:插件 577 项通过、1 项原有待办,类型检查、生成产物构建和使用本机固定版本的离线配置校验通过;两端缓存单元与模拟器证据见各自文档。随 0.9.8(2026-10-18)发布;真机与系统分享仍未验收。
2336
+
2337
+ ## 2026-10-30 — 发布 `dsh-deeppilot@0.9.13`
2338
+
2339
+ - **版本收口。** `0.9.12` 的版本提交 `a5a6f59` 曾落在 `main`,但从未打 tag、上传 npm 或建 GitHub Release;本次在 `0.9.11` 之上统一收口为 `0.9.13`:八版白名单(新增 `0.2.1-rc.4` 与 `0.2.2-alpha.2`,`SessionController.inspect` 缺失时 `sessions.history` 走 `page`)、运行中排队与转向、Markdown 导出、实时流式增量、插件自更新、设置页重设计,以及 helper 上报内嵌 Tailscale 版本后的六平台 `bin/` 重建。
2340
+ - **安装面。** `engines.dsh` 与十条 `dsh-*` peer 枚举八个精确版本;vendor peer 追加 `cordis ~4.0.6-alpha.1` / `schemastery ~3.18.6-alpha.1`;无配置字段变化。审计与隔离宿主证据见 `.alpha2-verify/`、`.rc4-verify/`(`0.2.1-rc.4` 27/27、`0.2.2-alpha.2` 32/32)。
2341
+ - **本地校验(发布工作树)。** `npm ci`;`npm test` 679 项(677 通过、1 项环境门禁跳过、1 项有意 TODO、0 失败);`typecheck`;`build`(`lib/` 无变化);`check:config-schema`(0.2.0-rc.2 CLI);`smoke:helper`(darwin-arm64);`go test ./...`;`bin/SHA256SUMS` 6/6;六平台 helper 重建后 `bin/` 无漂移;`npm pack` 69 项、51,405,933 字节。
2342
+ - **发布。** 发布提交 `0107efb584be4031af7279eb9f6cdf4404189081`,附注标签 `v0.9.13`;CI `40910195877` 与 CodeQL `40910195831` 绿色。`publish.yml` 首次运行 `40911590022` 的上传与来源证明步骤成功,但末尾核对在 24 次重试后仍 404,整次运行标红;重跑 `40918429580` 在发布步骤报 `E409 Cannot publish over previously staged version "0.9.13"`,由此确认**当前可信发布者绑定只允许暂存发布**:版本进入 npm staged 区,需维护者 2FA 批准后才公开。维护者批准后,注册表 `latest = 0.9.13`。
2343
+ - **发布后核验。** 来源证明类型 `https://slsa.dev/provenance/v1`,`gitCommit` 为发布提交,工作流引用 `refs/tags/v0.9.13`,invocation 为 `40911590022`;tarball SHA1 `ca2c754e3421cddd14a795c5b4d869c5ea4b3cf9`、SHA512 与注册表一致,69 个条目、解包 131,263,175 字节。全新隔离 `DSH_HOME`(`/tmp/dsh-verify-0913`,pnpm 从 npm 安装,不是 link)在真实 `0.2.2-alpha.2` 宿主上启动,`https://127.0.0.1:3098/phone/health` 返回 200,`serverVersion` 为 `0.9.13`、`dataPlane: true`;GitHub Release 在这一步通过后才公开并标记 Latest。
2344
+ - **流程变更。** 用户决定保留暂存流程;批准步骤与「工作流末尾核对在批准前必然失败」已写入 `docs/NPM_PUBLISHING.md` 与 `AGENTS.md` 发布第 4–5 步。工作流本身未改:末尾核对在 staged 版本上仍会标红,是否改成「检测到 staged 即视为成功并输出待批准」留待下次发布前决定。
2345
+ - **局限。** 未做真机、Funnel 端到端、真实 `updateBundle`/HMR 回滚安装,也没有在 `0.2.1-rc.4` 上做真实业务回合;上述健康检查只证明插件能被宿主组合、启动并应答。
@@ -34,6 +34,12 @@
34
34
  npm 不在保存配置时验证绑定;首次发布成功才证明认证可用。
35
35
  4. 新绑定必须在 **2 天内完成首次成功发布**。因此准备好新版本后再绑定;若过期,
36
36
  删除过期绑定并重新创建。先验证可信发布成功,再按需调整原有令牌发布权限。
37
+ 5. **2026-10-29 实测:当前绑定只允许暂存发布。** `publish.yml` 里的 `npm publish`
38
+ 不再直接公开版本,而是把它送进 staged 区(命令返回成功并提示“正在处理”,
39
+ 但注册表的版本、tarball 与来源证明持续 404)。用户决定**保留暂存流程**:
40
+ 每次发版由工作流暂存,维护者用 2FA 批准后才公开(步骤见第三节)。
41
+ 若要恢复直接发布,需在包设置的 Trusted Publisher 中勾选 `Allow npm publish`
42
+ (账户强制 2FA 时可能不可用),并同步改本节、AGENTS.md 与第 4 步的核对逻辑。
37
43
 
38
44
  ## 三、每次发布
39
45
 
@@ -63,7 +69,14 @@
63
69
  压缩包发布跳过生命周期脚本(`--ignore-scripts`);测试、类型检查和构建已在前序
64
70
  步骤执行,打包仍执行 `prepack`(打包前构建)。发布后核对版本、分发标签、
65
71
  压缩包完整性和来源证明元数据。
66
- 6. 确认 npm 包可安装,在全新 DSH 配置中完成安装验证后,再公开 GitHub 发布草稿。
72
+ 6. **批准暂存版本(暂存模式下必需)。** 工作流把版本送进 staged 区后,由维护者完成
73
+ 2FA 批准:在 npmjs.com 的 **Staged Packages** 标签找到
74
+ `dsh-deeppilot@<版本>` → Approve;或本机 `npm login` 后
75
+ `npm stage list dsh-deeppilot` → `npm stage approve <id>`。
76
+ 批准即公开该版本,并按发布命令写入分发标签(`latest` / `alpha`)。
77
+ 工作流末尾「核对发布版本、包完整性与来源证明」在批准前必然 404 失败、整次运行标红;
78
+ 这是暂存模式的预期结果,不代表上传失败,发布证据以批准后的手工核验为准。
79
+ 7. 确认 npm 包可安装,在全新 DSH 配置中完成安装验证后,再公开 GitHub 发布草稿。
67
80
  工作流不自动公开发布草稿;npm 上传和发布后的核对分别记录在步骤中。
68
81
 
69
82
  ## 四、失败处理与证据边界
@@ -136,6 +149,45 @@
136
149
  端口而失败,属环境冲突,不是插件问题。GitHub Release 在这一步通过后才公开并标记
137
150
  Latest。是否再放宽核对窗口,留待下次发布前决定,本次未改工作流。
138
151
 
152
+ 10. `0.9.11` 的实际发布结果(2026-10-24):附注标签 `v0.9.11` 指向
153
+ `a12750c84f1c2ecd579f87f3b5d60507fa3a7112`,该提交的 CI(运行号 `40055850654`,
154
+ 4 分 42 秒)与 CodeQL(运行号 `40055850739`,2 分 20 秒)均为绿。`publish.yml`
155
+ 在该标签上运行(运行号 `40056208123`),**24 个步骤全部成功**,包含最后的
156
+ 「核对发布版本、包完整性与来源证明」——这一步在 `0.9.5`~`0.9.9` 多次因注册表
157
+ 可见性延迟而失败,本次一次通过。注册表核验:`latest = 0.9.11`;tarball SHA1
158
+ `0a3e29b32beb393c7324d741602b5be1dc495d87`、SHA512 与来源证明主体一致、共
159
+ 68 个条目、解包 131,040,038 字节(与发布前 `npm pack --dry-run` 的
160
+ `unpackedSize` 完全一致);来源证明类型为 `https://slsa.dev/provenance/v1`,
161
+ `gitCommit` 正是该发布提交,工作流引用 `refs/tags/v0.9.11`。
162
+ **注册表可见性延迟仍然存在**:发布后约 3 分钟内
163
+ `dsh-deeppilot-0.9.11.tgz` 持续返回 `HTTP 404`(第 10 次探测才变 200),
164
+ 因此用它做安装验证必须带重试。随后在全新隔离 `DSH_HOME`
165
+ (`npm install dsh-deeppilot@0.9.11`,不是 link)中用真实 `0.2.1-rc.3` 宿主
166
+ 启动,插件日志出现 4 条 `[deeppilot]`,自有端口
167
+ `https://127.0.0.1:3098/phone/health` 返回 200 且 `serverVersion` 为 `0.9.11`;
168
+ GitHub Release 在这一步通过后才公开,并标记 Latest。
169
+ **遗留处理:** `0.9.10` 的 GitHub Release 原为 Draft,按用户决定于本轮**删除**
170
+ (远端标签 `v0.9.10` 与 npm 上的 `0.9.10` 包均保留,未做任何版本删除或回撤)。
171
+
172
+ 11. `0.9.13` 的实际发布结果(2026-10-29/30):附注标签 `v0.9.13` 指向
173
+ `0107efb584be4031af7279eb9f6cdf4404189081`,该提交的 CI(运行号
174
+ `40910195877`,7 分 27 秒)与 CodeQL(运行号 `40910195831`)均绿。
175
+ `publish.yml` 首次运行 `40911590022` 的上传与来源证明步骤成功,但末尾核对在
176
+ 24 次重试后仍抛 `读取 npm 发布信息失败(dsh-deeppilot/0.9.13,HTTP 404)`,
177
+ 整次运行标红;重跑 `40918429580` 在发布步骤报
178
+ `E409 Cannot publish over previously staged version "0.9.13"`。由此确认
179
+ **当前绑定只允许暂存发布**,版本进入 staged 区后需维护者 2FA 批准(见第二节
180
+ 第 5 条与第三节第 6 步)。批准后注册表 `latest = 0.9.13`;来源证明类型为
181
+ `https://slsa.dev/provenance/v1`、`gitCommit` 为该提交、工作流引用
182
+ `refs/tags/v0.9.13`、invocation 为 `40911590022`;tarball SHA1
183
+ `ca2c754e3421cddd14a795c5b4d869c5ea4b3cf9` 与 SHA512 同注册表一致,共 69 个
184
+ 条目、解包 131,263,175 字节。随后在全新隔离 `DSH_HOME` 中从 npm 安装
185
+ `dsh-deeppilot@0.9.13`(pnpm 安装,不是 link),用真实 `0.2.2-alpha.2` 宿主
186
+ 启动,插件自有端口 3098 的 `/phone/health` 返回 200,`serverVersion` 为
187
+ `0.9.13`、`dataPlane: true`;GitHub Release 在这一步通过后才公开并标记 Latest。
188
+ 暂存流程与批准步骤已写入第二、三节与 `AGENTS.md`;工作流末尾核对在暂存模式下
189
+ 的标红问题本轮未改,留待下次发布前决定是否检测 staged 后按成功处理。
190
+
139
191
  ## 五、官方资料
140
192
 
141
193
  1. [npm 可信发布配置与限制](https://docs.npmjs.com/trusted-publishers/)