dsh-deeppilot 0.8.2 → 0.9.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/COMPATIBILITY.md CHANGED
@@ -1,11 +1,11 @@
1
1
  # Compatibility
2
2
 
3
- This branch targets **DSH 0.1.7-rc.1**. The DSH peer dependencies and the development packages are pinned to that exact release. Earlier DSH builds and later release candidates are outside this branch's support scope.
3
+ This branch targets **DSH 0.2.0-rc.1**. The DSH peer dependencies and the development packages are pinned to that exact release. Earlier DSH builds and later release candidates are outside this branch's support scope.
4
4
 
5
5
  | Component | Current contract | Evidence |
6
6
  |---|---|---|
7
7
  | Node.js | 22 or newer | Package engine and CI |
8
- | DSH CLI and Host API | `0.1.7-rc.1` | Peer metadata, source typecheck, unit tests, bundle build, and config schema projection against rc.1 |
8
+ | DSH CLI and Host API | `0.2.0-rc.1` | Peer metadata, source typecheck, unit tests, bundle build, and config schema projection against a real 0.2.0-rc.1 CLI |
9
9
  | iOS bridge | DeepPilot protocol v2 | Bridge protocol tests; device behavior must be checked with the running Host and app |
10
10
  | Remote access | Tailscale Funnel on ports 443, 8443, or 10000 | Helper and supervisor tests |
11
11
 
@@ -21,9 +21,59 @@ This branch targets **DSH 0.1.7-rc.1**. The DSH peer dependencies and the develo
21
21
 
22
22
  - Protocol v2 is the only supported phone wire version. Protocol-v1 devices must pair again. The LAN listener uses its own TLS identity and certificate pinning; old LAN pairings without a fingerprint must also pair again.
23
23
  - The current app accepts the `deeppilot://pair` link and the JSON pairing payload. Bearer authentication, URL credentials, and first-frame shared tokens are rejected; devices register a P-256 public key and sign each WebSocket challenge.
24
- - The plugin's persisted device and Funnel state migration remains separate from DSH API version support. Session logs written by earlier DSH builds are readable only when the rc.1 Host's own history reader accepts them; this plugin does not rewrite those logs.
24
+ - The plugin's persisted device and Funnel state migration remains separate from DSH API version support. Session logs written by earlier DSH builds are readable only when the current Host's own history reader accepts them; this plugin does not rewrite those logs.
25
25
  - An unavailable optional OS facility, transport, or controller disables its dependent capability without crashing the Host.
26
26
 
27
+ ## Schedules require an optional DSH bundle
28
+
29
+ DSH 0.2.0 moved automation out of the shipped Web composition. The shipped
30
+ `packages/bundle/web-app/cordis.patch.yml` no longer carries the `time-context`,
31
+ `schedule`, or `ui-schedule` rows; they are supplied by the optional
32
+ `@deepseek-ai/dsh-experimental-schedule-bundle`, which ships switched off and is
33
+ enabled by the user through **Automation tasks** in the plugin manager.
34
+
35
+ The plugin needs no change for this. It still resolves the service through
36
+ `ctx.get('schedule')`, never declares `schedule` in `inject`, and reports
37
+ `welcome.capabilities.schedules = false` with a stable `E_UNSUPPORTED` for every
38
+ schedule frame when the service is absent. What changes is that a stock 0.2.0
39
+ Host now always takes that degraded path, so the phone tells the user to enable
40
+ Automation tasks instead of reporting a generic capability gap.
41
+
42
+ The capability is resolved lazily rather than captured when the bridge is
43
+ built. The bridge mounts on `sessionController` / `connection` /
44
+ `typertGateway`, all of which become ready before the optional Schedule service
45
+ finishes its own initialization, so a probe taken at that moment would report
46
+ `false` for the bridge's whole lifetime. With the bundle enabled, a live
47
+ 0.2.0-rc.1 host advertises `schedules=true` and the schedule
48
+ list/create/history/delete flow passes.
49
+
50
+ ## 0.2.0-rc.1 audit outcome
51
+
52
+ The source-level audit of `dsh-v0.2.0-rc.1` against the previous baseline
53
+ `dsh-v0.1.7-rc.2` found no breaking change in the DSH service surfaces the
54
+ plugin calls. Of the 78 service-surface files compared, 75 are byte-identical
55
+ and the three that changed are additive: `fork()` gained an optional
56
+ `onCreated` callback, and a `run()` helper call gained an internal `'hidden'`
57
+ argument. The `api/gateway` package, including the `wireStream.open` argument
58
+ order, is unchanged, as are the Typert protocol exports, `configForms`, and
59
+ every `schedule` source file.
60
+
61
+ The exact 0.2.0-rc.1 package pins, the regenerated registry lockfile (228
62
+ packages, all carrying `resolved` and `integrity`), the compatibility
63
+ assertions, generated output, unit tests, typecheck, build, Go helper tests,
64
+ helper checksums, and a config-schema check against a real 0.2.0-rc.1 CLI all
65
+ pass locally. A real 0.2.0-rc.1 `web` profile smoke test also passes: 25 checks,
66
+ 0 failures, driven by `scripts/smoke-live.mts` in the source repository (it is
67
+ a maintainer tool and is not part of the published package) against a booted
68
+ profile. Approval and question round trips are the one gap —
69
+ the stock profile auto-approves tool calls, so those paths need a profile with
70
+ a restrictive tool policy. The planned phone additions for durable schedules
71
+ and session forking are specified in
72
+ [`docs/DEEPPILOT_FEATURE_PLAN.md`](./docs/DEEPPILOT_FEATURE_PLAN.md); they are
73
+ not advertised until the protocol, iOS mirror, and integration tests land.
74
+
75
+ The complete audit evidence and re-audit procedure remain in [`docs/DSH_RELEASE_MEMORY.md`](./docs/DSH_RELEASE_MEMORY.md).
76
+
27
77
  ## Evidence limits
28
78
 
29
79
  Unit tests and config schema projection do not prove every network, Mac, Linux, Windows, or iPhone combination. In particular, physical-device performance, signed helper distribution, and production APNs delivery need their own checks. Include the exact DSH version, plugin commit, Node version, OS, connection mode, and sanitized status output when reporting a compatibility issue; never include credentials or message content.
package/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
 
10
10
  The open-source DSH companion plugin for **DeepPilot**, a native iPhone client
11
11
  for using DeepSeek Harness remotely. It connects the app directly to the DSH
12
- Host on your own Mac and does not replace or modify the DSH Web UI.
12
+ Host on your own computer and does not replace or modify the DSH Web UI.
13
13
 
14
14
  > DeepPilot is currently in TestFlight review. The invitation link will accept
15
15
  > testers after Apple approves the build.
@@ -32,12 +32,12 @@ Host on your own Mac and does not replace or modify the DSH Web UI.
32
32
 
33
33
  ## Install from npm
34
34
 
35
- This source checkout targets Node.js 22+ and **DSH 0.1.7-rc.1** with a `web` profile. The package includes
35
+ This source checkout targets Node.js 22+ and **DSH 0.2.0-rc.1** with a `web` profile. The package includes
36
36
  Funnel helpers for macOS, Linux, and Windows on amd64/arm64; trusted-LAN mode
37
37
  does not require the helper.
38
38
 
39
39
  The current working tree pins its DSH packages and compatibility checks to
40
- `0.1.7-rc.1`. A previously published plugin package may still carry its own
40
+ `0.2.0-rc.1`. A previously published plugin package may still carry its own
41
41
  older compatibility declaration until a release is made from this tree.
42
42
 
43
43
  ```sh
@@ -80,12 +80,12 @@ DeepPilot state under `$DSH_HOME/deeppilot/`.
80
80
 
81
81
  ## Publishing (maintainers)
82
82
 
83
- Release from this branch only after validating against DSH `0.1.7-rc.1`:
83
+ Release from this branch only after validating against DSH `0.2.0-rc.1`:
84
84
 
85
85
  1. Bump `version` in `package.json` and in the root `""` entry of
86
86
  `package-lock.json`, then run `npm test && npm run typecheck && npm run build`
87
87
  and inspect `npm pack --dry-run --json`. The compatibility metadata test
88
- enforces the exact rc.1 peer and development dependency versions.
88
+ enforces the exact audited peer and development dependency versions.
89
89
  2. Commit the release and push it. `npm publish` runs `prepack` (build) and
90
90
  `prepublishOnly` (test + typecheck) automatically.
91
91
  3. Publish pre-releases without touching `latest`:
@@ -95,7 +95,7 @@ Release from this branch only after validating against DSH `0.1.7-rc.1`:
95
95
  ```
96
96
 
97
97
  After a successful publish, verify the dist tag and install the package in
98
- a DSH `0.1.7-rc.1` profile before pointing users at it.
98
+ a DSH `0.2.0-rc.1` profile before pointing users at it.
99
99
  4. Tag the release commit `vX.Y.Z` and prepare a GitHub Release
100
100
  (English + 简体中文 notes) that links this README section.
101
101
  5. Publish stable releases with `npm publish --tag latest`, which moves
@@ -117,7 +117,10 @@ connection, one-time pairing, and health endpoints, not the complete DSH Web UI.
117
117
  The DeepPilot settings page exposes **Connections per public source** under
118
118
  the collapsed **Advanced settings** section. It defaults to `8`, accepts
119
119
  `1`–`16`, and briefly restarts the Funnel helper when changed, so connected
120
- remote clients reconnect once.
120
+ remote clients reconnect once. The device list also supports a custom name for
121
+ each paired device. Names are stored in the host registry and survive iPhone
122
+ reconnects or changes to the system-reported name; saving an empty value restores
123
+ the iPhone-reported default.
121
124
 
122
125
  Offline push is optional. Relay mode sends only the target APNs device token
123
126
  and a limited notification payload; full conversation history and live output
package/README.zh-CN.md CHANGED
@@ -8,7 +8,7 @@
8
8
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
9
9
 
10
10
  **DeepPilot** 的开源 DSH 配套插件。DeepPilot 是一款原生 iPhone 客户端,
11
- 可远程使用 DeepSeek Harness;插件让 App 直接连接用户自己 Mac 上的 DSH Host,
11
+ 可远程使用 DeepSeek Harness;插件让 App 直接连接用户自己电脑上的 DSH Host,
12
12
  不会替换或修改 DSH Web UI。
13
13
 
14
14
  > DeepPilot 目前正在等待 TestFlight 审核。Apple 审核通过后,邀请链接即可加入测试。
@@ -30,10 +30,10 @@
30
30
 
31
31
  ## 从 npm 安装
32
32
 
33
- 当前源码仅面向 Node.js 22+ 与带 `web` profile 的 **DSH 0.1.7-rc.1**。npm 包内置 macOS、Linux、Windows
33
+ 当前源码仅面向 Node.js 22+ 与带 `web` profile 的 **DSH 0.2.0-rc.1**。npm 包内置 macOS、Linux、Windows
34
34
  的 amd64/arm64 Funnel helper;可信局域网模式不依赖 helper。
35
35
 
36
- 当前工作树的 DSH 包和兼容性检查均固定为 `0.1.7-rc.1`。从此工作树发布新版本前,
36
+ 当前工作树的 DSH 包和兼容性检查均固定为 `0.2.0-rc.1`。从此工作树发布新版本前,
37
37
  已发布的旧插件包仍可能带有各自的旧兼容声明。
38
38
 
39
39
  ```sh
@@ -68,12 +68,12 @@ dsh plugin --profile web remove dsh-deeppilot
68
68
 
69
69
  ## 发布说明(维护者)
70
70
 
71
- 此分支仅在 DSH `0.1.7-rc.1` 下完成验证后发布:
71
+ 此分支仅在 DSH `0.2.0-rc.1` 下完成验证后发布:
72
72
 
73
73
  1. 同步修改 `package.json` 与 `package-lock.json` 根 `""` 条目中的
74
74
  `version`,然后运行 `npm test && npm run typecheck && npm run build`,
75
75
  并检查 `npm pack --dry-run --json`。兼容性元数据测试会校验 peer 与开发依赖
76
- 均固定为 rc.1。
76
+ 均固定为当前审计基线。
77
77
  2. 提交发布并推送。`npm publish` 会自动执行 `prepack`(构建)与
78
78
  `prepublishOnly`(测试 + 类型检查)。
79
79
  3. 发布预发布版本,不要动 `latest`:
@@ -82,7 +82,7 @@ dsh plugin --profile web remove dsh-deeppilot
82
82
  npm publish --tag alpha
83
83
  ```
84
84
 
85
- 发布成功后检查 dist tag,并在 DSH `0.1.7-rc.1` profile 中安装验证发布的包。
85
+ 发布成功后检查 dist tag,并在 DSH `0.2.0-rc.1` profile 中安装验证发布的包。
86
86
  4. 为发布提交打 `vX.Y.Z` tag,并准备包含英文与简体中文说明的
87
87
  GitHub Release,链接本 README 的发布说明。
88
88
  5. 稳定版用 `npm publish --tag latest` 发布,使 `latest` 切换到新版本。
@@ -101,7 +101,9 @@ DSH Web UI。
101
101
 
102
102
  DeepPilot 设置页在默认折叠的“高级设置”中提供“每个公网来源的连接上限”,默认
103
103
  `8`,可设置为 `1`–`16`。修改后 Funnel helper 会短暂重启,已连接的远程客户端
104
- 会自动重连一次。
104
+ 会自动重连一次。设备列表支持为每台已配对设备设置自定义名称;名称会保存在主机
105
+ 设备注册表中,即使 iPhone 重连或上报了新的系统名称也不会被覆盖。留空保存可恢复
106
+ iPhone 上报的默认名称。
105
107
 
106
108
  离线推送是可选功能。中继模式只发送目标 APNs 设备 Token 和有限的通知内容;
107
109
  完整会话历史与实时输出不会经过中继。启用远程访问或推送前,请阅读
package/SKILL.md ADDED
@@ -0,0 +1,87 @@
1
+ ---
2
+ name: dsh-release-audit
3
+ description: Audit DeepSeek Harness releases for the dsh-deeppilot plugin. Use when a DSH version changes, when checking plugin compatibility, or when looking for new DSH capabilities that could become safe DeepPilot features.
4
+ ---
5
+
6
+ # DSH release audit for DeepPilot
7
+
8
+ Use this skill to keep the public `dsh-deeppilot` plugin aligned with DeepSeek
9
+ Harness without repeatedly rediscovering the compatibility rules.
10
+
11
+ ## Source of truth
12
+
13
+ Read these files before making a compatibility decision:
14
+
15
+ - `docs/DSH_RELEASE_MEMORY.md` — the last audited release, risk decisions,
16
+ feature opportunities, and the re-audit rule;
17
+ - `COMPATIBILITY.md` — the currently supported DSH baseline and validation
18
+ limitations;
19
+ - `AGENTS.md` — repository contracts and validation requirements;
20
+ - `package.json` and `package-lock.json` — the exact DSH peer/development pins.
21
+
22
+ Treat the official DSH release page and tagged source as evidence, not the
23
+ release-note summary alone.
24
+
25
+ ## Audit workflow
26
+
27
+ 1. Identify the new DSH tag and the last audited tag. Fetch the official
28
+ release page and the complete tag-to-tag comparison.
29
+ 2. Read this repository's `package.json`, lockfile, compatibility assertions,
30
+ and DSH adapter source. Identify the exact Host services, Events, Remote
31
+ methods, Gateway carriers, and Client bundles that the plugin imports.
32
+ 3. Inspect the corresponding tagged DSH source for each used surface. Check
33
+ method presence, argument/result shapes, stream envelopes, lifecycle
34
+ behavior, and package version constraints.
35
+ 4. Classify the result separately as:
36
+ - **install/deployment**: package metadata, peer constraints, loader and
37
+ profile compatibility;
38
+ - **runtime**: Host service, Gateway, Cordis lifecycle, and event behavior;
39
+ - **phone protocol**: DeepPilot `PROTOCOL.md` v2, iOS mirror, pairing,
40
+ replay, and authorization boundaries.
41
+ 5. Identify new capabilities. For each candidate, state the user value, the
42
+ DSH API it would use, the required DeepPilot protocol/UI work, the
43
+ authorization scope, and the tests needed before shipping it.
44
+ 6. Update `docs/DSH_RELEASE_MEMORY.md` with the tag, date, evidence links,
45
+ decision, risks, feature backlog, and upgrade gate. Update
46
+ `COMPATIBILITY.md` when the supported baseline changes.
47
+ 7. Never claim a release is supported until the dependency pins, generated
48
+ output, automated checks, and a real DSH Host smoke test have passed.
49
+
50
+ ## DeepPilot-specific rules
51
+
52
+ - Keep `/phone` and `/phone/health` compatible with the current iOS app.
53
+ - Treat `PROTOCOL.md` as normative. Any phone wire change must update the
54
+ TypeScript mirror and coordinate with the private iOS repository.
55
+ - Protocol v2 is the current baseline. New optional capabilities should be
56
+ capability-gated; do not silently change existing frame meanings.
57
+ - A DSH controller change belongs behind the stable `ApiProxyLike` boundary;
58
+ do not leak DSH controller shapes into the phone protocol.
59
+ - Reminder prompts, message bodies, pairing tokens, APNs tokens, relay
60
+ credentials, and tool arguments must not be written to logs.
61
+ - New file-open or shell-like behavior must use DSH's verified Host path seam
62
+ and explicit user confirmation. Never add arbitrary remote command execution.
63
+ - Scheduled tasks must remain bound to their original DSH Session and use a
64
+ dedicated authorization scope when exposed to phones.
65
+
66
+ ## Required validation
67
+
68
+ For documentation-only audits, run `git diff --check` and verify every link.
69
+ For an actual DSH dependency upgrade, run the repository's full release
70
+ checklist, including tests, typecheck, build, config schema projection, Go
71
+ helper tests, and binary checksums. Add a real DSH `web` profile smoke test for
72
+ sessions, history, prompts, models, workspaces, approvals, questions, replay,
73
+ and any newly exposed capability.
74
+
75
+ ## Output format
76
+
77
+ When reporting an audit, lead with one of these verdicts:
78
+
79
+ - **compatible** — tested and ready to support;
80
+ - **source-compatible, upgrade required** — no code break found, but pins or
81
+ validation still block release;
82
+ - **runtime risk** — a used service or event needs an integration change;
83
+ - **protocol impact** — DeepPilot/iOS wire coordination is required;
84
+ - **unsupported** — a confirmed incompatibility remains.
85
+
86
+ Never turn a source-level review into a false claim of runtime or iPhone
87
+ compatibility.
@@ -0,0 +1,274 @@
1
+ # DSH release compatibility memory
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
7
+
8
+ - **Audited release:** `dsh-v0.2.0-rc.1` (published 2026-09-28; official release
9
+ page: <https://github.com/deepseek-ai/deepseek-harness/releases/tag/dsh-v0.2.0-rc.1>).
10
+ - **Comparison baseline:** `dsh-v0.1.7-rc.2` (the previous plugin baseline).
11
+ - **Plugin runtime verdict:** **no breaking change in the DSH APIs that DeepPilot
12
+ currently calls**. 75 of 78 compared service-surface files are byte-identical;
13
+ the three that changed are additive.
14
+ - **Install/deployment verdict:** the exact peer/dev pins, the registry lockfile
15
+ (228 packages, all carrying `resolved` and `integrity`), the compatibility
16
+ assertions, generated `lib/`, 303 unit tests, typecheck, build, Go helper
17
+ tests, helper checksums, and a config-schema check against a **real
18
+ `0.2.0-rc.1` CLI** all pass locally. A real `0.2.0-rc.1` `web` profile smoke
19
+ test now also passes — 25 checks, 0 failures — via
20
+ `scripts/smoke-live.mts`. Two behaviours remain unverified there and are
21
+ listed under the 2026-09-29 findings: approval/question round trips (the
22
+ stock profile auto-approves tools) and the immediate consistency of the
23
+ archived list.
24
+ - **Protocol verdict:** no required DeepPilot phone-protocol break. Protocol v2,
25
+ pairing state, and device records are unchanged; already-paired phones need no
26
+ action.
27
+ - **One behavioural change:** DSH 0.2.0 moved automation out of the shipped Web
28
+ composition. See "Automation is now an optional bundle" below. The plugin needs
29
+ no code change; the phone's copy now points at the bundle.
30
+
31
+ ## 2026-09-28 — audit of `dsh-v0.2.0-rc.1`
32
+
33
+ ### Scope and method
34
+
35
+ Compared `dsh-v0.1.7-rc.2...dsh-v0.2.0-rc.1` (261 commits, 1109 files). Rather
36
+ than read release notes, every DSH package the plugin actually imports was
37
+ compared file by file: `api/session-controller` (34 files),
38
+ `api/workspace-controller` (10), `schedule/schedule` (10), `api/gateway` (11),
39
+ and `typert/protocol` + `settings/settings` (13). Release notes were treated as
40
+ a hint, never as evidence.
41
+
42
+ ### Findings by risk class
43
+
44
+ | Area | Finding | DeepPilot impact |
45
+ | --- | --- | --- |
46
+ | Install | All ten peer and five dev packages publish `0.2.0-rc.1` on npm. `cordis` stays `4.0.4`, `schemastery` stays `3.18.4`, Node `engines` and pnpm `11.7.0` are unchanged. The lockfile had to be regenerated from the registry: the old one still pinned `0.1.7-rc.2` and made both `npm ci` and `npm install` fail with ERESOLVE. | Resolved. `npm ci`, typecheck, build, and the real-CLI config-schema check all pass. |
47
+ | Session / Workspace controllers | `client/contract/sessions.ts` and `client/sessions/service.ts` changed only to add an **optional** `onCreated?: (childId: SessionId) => void` to `fork()`. `workspace-controller/src/default-directory.ts` changed only to pass an extra internal `'hidden'` argument to its own `run()` helper. | Additive. The plugin's hand-written `SessionControllerLike` / `WorkspaceControllerLike` mirrors still match. |
48
+ | Schedule service | **All ten `schedule/schedule/src` files are byte-identical to rc.2.** The change is packaging, not API: see below. | The existing facade needs no change. |
49
+ | Gateway / Remote Events | **All eleven `api/gateway/src` files are byte-identical**, including `stream-protocol.ts` and `stream-server.ts`. `typertGateway.wireStream.open(endpoint, payload, uplink, peer, signal)` keeps its argument order — the order DSH changed once in 0.1.7. | The highest-risk integration seam is unchanged. Approval and question delivery re-run clean on the new baseline. |
50
+ | Typert / settings | `typert/protocol` and `settings/settings` sources are byte-identical, so `TypertRemoteService`, `InvocationDescriptor`, `TypertCodec`, `TypertRemoteContribution`, `TypertSchema`, and `configForms.get` are all unaffected. | No change. |
51
+ | Phone protocol | No DSH-facing wire change. Protocol v2, `schedule.manage` scope, and the mutation journal are untouched. | Paired phones keep working. |
52
+
53
+ ### Automation is now an optional bundle
54
+
55
+ The shipped `packages/bundle/web-app/cordis.patch.yml` in rc.2 carried
56
+ `time-context`, `schedule`, and `ui-schedule` at lines 118–126 and 370–371. In
57
+ 0.2.0-rc.1 that file contains no schedule rows at all. Those three rows are now
58
+ inserted by `packages/experimental/schedule-bundle`
59
+ (`@deepseek-ai/dsh-experimental-schedule-bundle`), which `OPTIONAL_BUNDLES` in
60
+ `packages/boot/app-boot/src/profile.ts` ships **switched off**; the user enables
61
+ it as **Automation tasks** in the plugin manager.
62
+
63
+ This is the only substantive product change in the release. The plugin's
64
+ existing design is already correct: it resolves the service via
65
+ `ctx.get('schedule')`, never puts `schedule` in `inject`, and degrades to a
66
+ stable `E_UNSUPPORTED` with `welcome.capabilities.schedules = false`. What
67
+ changed is that a stock host now always takes that degraded path, so the iOS
68
+ copy for the two schedule errors now names the bundle instead of reporting a
69
+ generic capability gap. `PROTOCOL.md` records that the capability bit reflects
70
+ actual mounting, not the host version.
71
+
72
+ ### Re-audit procedure used
73
+
74
+ To redo this comparison: `git clone --filter=blob:none --no-checkout
75
+ https://github.com/deepseek-ai/deepseek-harness.git`, fetch both tags, list each
76
+ package's `src/**/*.ts` from `git/trees/<sha>?recursive=1` at both commits, and
77
+ diff the two file sets file by file. Avoid `git grep` on a blob-filtered clone —
78
+ it re-fetches blobs and times out. Record which files are byte-identical, not
79
+ merely which packages still exist.
80
+
81
+ ## 2026-09-29 — live smoke test on a real `web` profile (0.2.0-rc.1)
82
+
83
+ ### How it was run
84
+
85
+ `scripts/smoke-live.mts` drives the phone protocol against a real
86
+ `dsh --profile <name> web` host that has this working copy linked in. It
87
+ asserts the seams unit tests fake out: the LAN TLS listener, the
88
+ challenge/prove handshake, and every Host RPC the bridge forwards through
89
+ `ctx.apiProxy`. It is repeatable, so the next DSH release can re-run it instead
90
+ of trusting a source diff.
91
+
92
+ ```sh
93
+ npx tsx scripts/smoke-live.mts register # pre-authorize a device, then restart the host
94
+ npx tsx scripts/smoke-live.mts run [--prompt] [--interactions]
95
+ ```
96
+
97
+ The pairing-code happy path is intentionally not driven: the code only exists
98
+ inside the host process and can only be minted through the plugin's own
99
+ `deeppilot/beginPairing` Host RPC, i.e. from a DSH client session. The script
100
+ asserts instead that `/phone/pair` is mounted and refuses a bogus code, and
101
+ covers the real challenge/prove handshake with a pre-authorized device.
102
+
103
+ ### Result: 25 checks pass, 0 fail
104
+
105
+ Verified on a real 0.2.0-rc.1 `web` profile: `/phone/health`, the WSS upgrade,
106
+ challenge/prove → welcome with all six scopes, session list/create/open/tail,
107
+ history paging, the model catalog and a live model switch, workspace
108
+ list/create, archive → archived list → unarchive, the pending approval/question
109
+ snapshot, a real model turn (`clientSendId` receipt `accepted`,
110
+ `message.final` + `turn.end` observed), disconnect/reconnect replay
111
+ (`resumed=true`, `s2c.resume.done` received), and — with the Automation tasks
112
+ bundle mounted — the schedule list/create/history/delete flow.
113
+
114
+ The TLS pin check is worth keeping: the bridge pins the **SPKI** digest
115
+ (`src/lan-tls.ts:35`), not the certificate DER, and the script's independently
116
+ computed pin matched the one the plugin logged on a live host.
117
+
118
+ ### Finding 1 — `--patch` does not install the plugin
119
+
120
+ Composing the plugin through `dsh --profile X --patch ./cordis.patch.yml`
121
+ leaves the profile with `deeppilot: failed to import` and no reason logged.
122
+ `dsh-app-boot/lib/index.js:3904` shows why: a bare specifier in a patch layer is
123
+ never resolved into a package, so the loader never creates a fiber for it. The
124
+ plugin only mounts after `dsh plugin --profile X add dsh-deeppilot@link:<path>`.
125
+ The install docs should say so; the silent failure looks exactly like a broken
126
+ plugin.
127
+
128
+ ### Finding 2 — `capabilities.schedules` stayed false even with the bundle enabled (fixed)
129
+
130
+ The optimistic reading of "Automation is now an optional bundle" above did not
131
+ hold on a real host. With
132
+ `@deepseek-ai/dsh-experimental-schedule-bundle` **installed and mounted** — the
133
+ bundle's three rows (`time-context`, `schedule`, `ui-schedule`) do reach the
134
+ composed profile, and `ScheduleService` still exposes
135
+ `create/list/catalog/history/delete/update` — welcome advertised
136
+ `schedules=false` and every `c2s.schedule.*` request took the `E_UNSUPPORTED`
137
+ path.
138
+
139
+ Root cause: the bridge is constructed from a `ctx.inject` on
140
+ `sessionController` / `connection` / `typertGateway` (`src/index.ts:1212`), and
141
+ `schedule` is deliberately **not** in that list. `DshApiProxy` then resolved
142
+ `ctx.get('schedule')` once in its constructor and cached it in a `readonly`
143
+ field. On DSH 0.2.0 those three services become ready well before
144
+ `ScheduleService` finishes its own async init, so the cached value was
145
+ `undefined` for the bridge's entire lifetime. Reordering `dsh.profile.bundles`
146
+ to mount the schedule bundle first did not help, which is what ruled out a
147
+ pure composition-order cause.
148
+
149
+ Fix: resolve the optional service lazily on every read and keep it once found
150
+ (`src/dsh-api-proxy.ts`). `capabilities` is already a getter, so a device that
151
+ connects after the service is up now gets `schedules=true`, and the full
152
+ create/list/history/delete flow passes on a live host. Covered by
153
+ `tests/dsh-api-proxy.test.ts`.
154
+
155
+ A profile that has not enabled the bundle still reports `schedules=false` and
156
+ still degrades to `E_UNSUPPORTED` — that path is unchanged.
157
+
158
+ ### Finding 3 — approvals are auto-approved on a default profile
159
+
160
+ `--interactions` produced a real `tool.start`/`tool.end` pair for a "create
161
+ this file" instruction but no `s2c.pending.approval`, so the stock profile
162
+ auto-approves and the approval round trip stays unverified. The question round
163
+ trip is also unverified: dispatching a second prompt into the same session
164
+ timed out on the delivery ack. Both need a profile with a restrictive tool
165
+ policy before they can be called verified.
166
+
167
+ ### Finding 4 — the archived mirror is stale right after archiving
168
+
169
+ `archiveSession` updates `archivedSessionIds` but does not call
170
+ `refreshSummaries()`, so `c2s.sessions.archived` can omit the session that was
171
+ just archived until an unrelated event triggers a refresh (it converged within
172
+ 10 s in practice). Pre-existing behaviour, not a 0.2.0 regression, but the app
173
+ must not assume the archived list is immediately consistent.
174
+
175
+ ## Previous decision — `dsh-v0.1.7-rc.2`
176
+
177
+ - **Audited release:** `dsh-v0.1.7-rc.2` (official release page: <https://github.com/deepseek-ai/deepseek-harness/releases/tag/dsh-v0.1.7-rc.2>).
178
+ - **Plugin runtime verdict:** **no confirmed breaking change in the DSH APIs
179
+ that DeepPilot currently calls**.
180
+ - **Install/deployment verdict:** the exact peer/dev pins and lockfile are now
181
+ updated to `0.1.7-rc.2`; `npm test`, `npm run typecheck`, `npm run build`, and
182
+ the rc.2 config-schema check pass locally. Support still awaits a real rc.2
183
+ `web` profile smoke test and the release checklist's clean-install gate.
184
+ - **Protocol verdict:** no required DeepPilot phone-protocol break was found in
185
+ the rc.2 release notes or the inspected rc.2 source. This does not waive the
186
+ normal integration test against a real rc.2 Host.
187
+ - **Current implementation:** the optional DSH Schedule facade, schedule phone
188
+ frames, `schedule.manage` authorization, DSH `schedule/changed` projection,
189
+ a prompt-free persistent mutation journal, and the DSH Session fork facade
190
+ with fork idempotency are implemented and locally tested. The private iOS
191
+ protocol mirror, BridgeClient/AppModel integration, reminder list/editor/
192
+ history UI, and message “Branch from here” action are implemented; real
193
+ Host/iPhone integration remains pending.
194
+
195
+ ## Evidence and risk assessment
196
+
197
+ | Area | rc.2 finding | DeepPilot impact |
198
+ | --- | --- | --- |
199
+ | Session controller | The rc.2 source still exposes the methods used by the adapter: `list`, `inspect`, `create`, `modelCatalog`, `selectModel`, `rename`, `prompt`, `attachment`, `cancel`, and `projections`. It adds `search`, `page`, `follow`, `fork`, `updateQueue`, `initializeDefaultModel`, and native workspace-path operations. | Existing calls are source-compatible at the inspected API level. New calls must remain optional and capability-gated. |
200
+ | Workspace controller | `create`, `archiveSession`, `unarchiveSession`, and `follow` remain. rc.2 adds rename/delete/order/pin operations and archive activity handling. | Existing bridge behavior is source-compatible. Archive behavior is stricter when a Session has active work, including scheduled reminders. |
201
+ | Gateway / Typert | The in-process `typertGateway.wireStream.open(endpoint, payload, uplink, peer, signal)` seam used by the resident approval/question Client remains. Typert registration still exposes `register(contribution)`. | No confirmed break in the resident Remote Events path. Re-run the approval/question tests on rc.2 because this is the highest-risk integration seam. |
202
+ | Release metadata | The plugin's peer/dev pins and lockfile now target rc.2 with real rc.2 integrity metadata. | Keep `package.json`, `package-lock.json`, compatibility assertions, generated `lib/`, and release documentation synchronized before claiming rc.2 support. |
203
+ | DSH event/history internals | rc.2 continues to evolve session projections, history paging, and assistant stream presentation. The plugin currently consumes the older `session/event`/`inspect` projection seam rather than the newer Remote `page`/`follow` surface. | Treat as a compatibility risk requiring a real Host smoke test, not as a confirmed wire break. Keep the phone protocol independent of DSH controller shapes. |
204
+
205
+ Official comparison: <https://github.com/deepseek-ai/deepseek-harness/compare/dsh-v0.1.7-rc.1...dsh-v0.1.7-rc.2>.
206
+
207
+ ## New rc.2 capabilities worth using
208
+
209
+ Prioritized for DeepPilot, in this order:
210
+
211
+ 1. **Durable reminders and schedules (highest value).** DSH now has
212
+ `schedule_create`, `schedule_list`, `schedule_delete`, and
213
+ `schedule_update`, persistent one-shot/fixed-rate/daily/weekly/cron tasks,
214
+ restart survival, delivery history, and a minimum one-minute interval. Add
215
+ an optional, session-bound schedule surface to the phone: list tasks, create
216
+ or edit a task, delete it, and show delivery history. Keep all operations
217
+ behind `sessions.manage` plus a dedicated schedule scope; never log reminder
218
+ prompts. A reminder must remain bound to its original Host Session.
219
+ *(Implemented in 0.8.3. As of DSH 0.2.0 this capability is no longer
220
+ bundled by default — see "Automation is now an optional bundle" above, and
221
+ any real-host verification must enable Automation tasks first.)*
222
+ 2. **Host Session search.** `sessionController.search(query)` returns bounded
223
+ snippets without activating an Agent. This maps naturally to a phone search
224
+ screen and can reduce the amount of history transferred over a mobile link.
225
+ Return only the bounded snippet/session identity and keep it in the
226
+ `sessions.read` authorization domain.
227
+ 3. **Conversation forking.** `sessionController.fork({ sessionId, atSeq? })`
228
+ enables a phone action such as “branch from this turn”. It is additive to
229
+ the phone protocol but needs an iOS mirror, cursor/ownership tests, and a
230
+ deliberate policy for subagent and archived Sessions.
231
+ 4. **Queue editing.** `sessionController.updateQueue` supports editing,
232
+ removing, or steering a pending queue item. This is useful for a phone when
233
+ a turn is already running, but it needs first-class queue UI and conflict
234
+ handling rather than silently changing the existing prompt path.
235
+ 5. **Open/reveal on the Mac.** rc.2 adds verified native workspace-path opening
236
+ and application discovery. This could power a deliberate “Reveal in Finder /
237
+ Open associated app” action. Keep the Host's path verification and show an
238
+ explicit confirmation on the phone; do not expose arbitrary shell access.
239
+
240
+ Features that are primarily Web/Desktop UX (onboarding, keyboard shortcut
241
+ management, archived-only filters, account/API-key model entry separation, and
242
+ background continuation) should not be copied into the phone plugin unless
243
+ they solve a mobile-specific need.
244
+
245
+ ## Required rc.2 upgrade gate
246
+
247
+ > Superseded by the 2026-09-28 `0.2.0-rc.1` audit at the top of this file. The
248
+ > gate below still applies to that release with one change: a schedule smoke
249
+ > test additionally requires the user to enable the **Automation tasks** bundle,
250
+ > because a stock 0.2.0 Host does not mount the Schedule service.
251
+
252
+ Do not call the rc.2 baseline fully supported until all of these are true:
253
+
254
+ 1. The exact DSH peer/dev pins and lockfile remain on `0.1.7-rc.2`.
255
+ 2. The plugin's full release checklist passes: `npm ci`, `npm test`,
256
+ `npm run typecheck`, `npm run build`, `npm run check:config-schema`, Go helper
257
+ tests, and the binary checksum verification.
258
+ 3. A real DSH rc.2 `web` profile smoke test covers: session list/open, history,
259
+ prompt, model selection, workspace list/create/archive/unarchive, approval,
260
+ question, and disconnect/reconnect replay.
261
+ 4. A phone-visible schedule create/list/update/delete/history flow is tested
262
+ after the schedule surface is implemented; a passing plugin build alone does
263
+ not prove mobile protocol compatibility.
264
+ 5. Fork is tested for exact event-prefix behavior, idempotent retries, and
265
+ original-session immutability after the fork surface is implemented.
266
+ 6. `COMPATIBILITY.md`, README compatibility text, generated `lib/`, and this
267
+ file are updated with the tested DSH version and intentional support range.
268
+
269
+ ## Re-audit rule
270
+
271
+ For every future DSH release, compare the new tag against the last audited tag,
272
+ inspect the package/service surfaces actually imported by this repository,
273
+ classify install/runtime/protocol risk separately, and append a dated decision
274
+ here. Do not treat a release-note summary as proof of compatibility.