dsh-ptc-plus 0.5.4 → 0.5.7
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.en.md +8 -4
- package/README.md +8 -4
- package/client.cjs +13 -23
- package/docs/adr/0005-temporary-rejected-cell-edit-transport.md +2 -2
- package/docs/adr/0017-track-the-latest-dsh-public-surface.md +4 -4
- package/docs/adr/0020-optional-cordis-tools-in-ptc-mode.md +18 -12
- package/docs/adr/0044-coexist-with-the-official-persistent-repl.md +2 -0
- package/docs/adr/0051-persist-explicit-host-environment-resets.md +29 -0
- package/docs/adr/README.md +1 -0
- package/docs/architecture.md +3 -3
- package/docs/durability-design.md +10 -0
- package/docs/installation.md +9 -9
- package/docs/publishing.md +1 -1
- package/docs/release-notes.md +1 -1
- package/docs/releases/v0.5.4.md +10 -6
- package/docs/releases/v0.5.5.md +41 -0
- package/docs/releases/v0.5.6.md +45 -0
- package/docs/releases/v0.5.7.md +51 -0
- package/docs/runtime-reference.md +4 -4
- package/internal/config-spec.js +2 -2
- package/internal/cordis-tools-owner.js +32 -28
- package/internal/edit-transport-owner.js +3 -2
- package/internal/execution-seam-compat.js +13 -15
- package/internal/host-tool-sdk.js +17 -29
- package/internal/runtime-bridge-owner.js +11 -9
- package/internal/runtime-messages.js +8 -0
- package/internal/session-journal-recovery.js +68 -25
- package/internal/session-journal-schema.js +10 -0
- package/internal/session-journal.js +25 -13
- package/internal/session-log-view.js +15 -8
- package/internal/session-runtime.js +13 -0
- package/package.json +8 -8
- package/src/client-activity.js +4 -1
- package/src/client-settings-view.js +3 -10
package/README.en.md
CHANGED
|
@@ -29,7 +29,7 @@ PTC Plus provides a stateful TypeScript computation environment for DSH's **PTC
|
|
|
29
29
|
|
|
30
30
|
## Quick start
|
|
31
31
|
|
|
32
|
-
Requires Node.js `^22.19.0 || >=24.0.0` and the
|
|
32
|
+
Requires the latest available official DSH release and a Node.js runtime satisfying both the plugin's `^22.19.0 || >=24.0.0` range and the selected DSH release's requirements:
|
|
33
33
|
|
|
34
34
|
```sh
|
|
35
35
|
dsh plugin --profile <profile> add dsh-ptc-plus
|
|
@@ -37,7 +37,7 @@ dsh plugin --profile <profile> add dsh-ptc-plus
|
|
|
37
37
|
|
|
38
38
|
Replace `<profile>` with your profile name, restart DSH, and select **PTC mode** in the session. Continuous computation, call tolerance, and global bindings are on by default. To upgrade, run `dsh plugin --profile <profile> add dsh-ptc-plus@latest` and restart that Host; see the [installation guide](docs/installation.md) for other installation methods, Desktop, the local development launcher, and troubleshooting.
|
|
39
39
|
|
|
40
|
-
The plugin declares
|
|
40
|
+
The plugin declares the DSH compatibility range `>=0.2.1-0 <0.2.3` for the Host's version preflight; public capability checks and packed tests verify integration within that range.
|
|
41
41
|
|
|
42
42
|
The session shows a **REPL** tab, and wide screens show a **PTC Plus** header indicator. The sparkle button beside the composer opens the global binding menu, the session capability workbench, and **PTC Plus settings**; **Plugins → Installed → dsh-ptc-plus → Configure** in the sidebar is the same configuration.
|
|
43
43
|
|
|
@@ -88,7 +88,7 @@ The default **stateful semantics** (`bindingUpdates: 'stateful'`) extend JavaScr
|
|
|
88
88
|
- Existing closures read the updated binding, a function value saved earlier is still the original function, and blocks, functions, and loop iterations keep their separate scopes.
|
|
89
89
|
- A failed initialization does not permanently reserve that name, and changes made before the failure are not rolled back.
|
|
90
90
|
|
|
91
|
-
Cells support TypeScript (including runtime `enum` and namespaces), top-level `await` / `return`, and static `import` / `export`; a static import takes effect before the whole cell body executes, and an assignment later in the body can override it.
|
|
91
|
+
Cells support TypeScript (including runtime `enum` and namespaces), top-level `await` / `return`, and static `import` / `export`; a static import takes effect before the whole cell body executes, and an assignment later in the body can override it. **Binding update semantics** in settings displays the current policy and offers **Allow redeclarations and overrides** (`stateful`) or **Protect names** (`protected`); protected runtime names such as `tools` can never be overwritten.
|
|
92
92
|
|
|
93
93
|
`run_code`, edited code, and the global binding workbench follow the same language policy, while explicit `eval`, `Function`, `node:vm`, and independent runtimes keep their own native boundaries. Scope, module interoperability, and historical session rules are in the [language reference](docs/runtime-reference.md#cell-semantics), and complete language rules, configuration fields, and diagnostics are in the [runtime reference](docs/runtime-reference.md).
|
|
94
94
|
|
|
@@ -182,7 +182,9 @@ Stopping a background subagent preserves the parent session's REPL state, so cal
|
|
|
182
182
|
|
|
183
183
|
Within the supported range of the plugin's graph IPC, program arguments, results, and recovery records keep `undefined`, BigInt, `NaN`, infinities, sparse arrays, cycles, and shared references, and supported values can be returned directly without writing `JSON.stringify` yourself (it drops object fields containing `undefined`, turns `NaN` and infinities into `null` and `-0` into `0`, and rejects BigInt). Functions, Promises, class instances, Date, Map, and Set are outside that range, and native `tools.*` JSON argument and result contracts do not change; see the [value contract](docs/value-wire.md).
|
|
184
184
|
|
|
185
|
-
Session state is not permanent memory: after a restart
|
|
185
|
+
Session state is not permanent memory: after a restart or context compaction, only state verifiable from session records whose provenance remains in the model's context is retained, and everything else is discarded with a diagnostic, continuing in an empty environment when necessary. Missing or damaged session records produce an explicit error instead of being treated as a successfully recovered empty session. Recovery neither redispatches recorded native-tool calls nor reverses historical external effects; see the [runtime reference](docs/runtime-reference.md) for its evidence and limits.
|
|
186
|
+
|
|
187
|
+
An explicit Host environment reset clears session variables, named checkpoints and edit targets, including after restart or fork. Completed external effects remain, and global binding configuration stays active.
|
|
186
188
|
|
|
187
189
|
## Boundaries
|
|
188
190
|
|
|
@@ -194,6 +196,8 @@ PTC Plus is a community plugin, with no affiliation with or endorsement from Dee
|
|
|
194
196
|
|
|
195
197
|
## Development
|
|
196
198
|
|
|
199
|
+
On Windows, double-click `scripts\run-dev-dsh.cmd` to start an isolated development environment. By default it reuses a port verified by Windows Node.js and replaces cached ports that are occupied or denied. Explicit port choices are preserved; see the [installation guide](docs/installation.md).
|
|
200
|
+
|
|
197
201
|
Development happens in the repository root: `npm ci` installs dependencies and `npm run build` regenerates `client.cjs` and the compiler artifacts. Focused tests require an explicit selection:
|
|
198
202
|
|
|
199
203
|
```sh
|
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ PTC Plus 为 DSH 的 **PTC 模式**提供有状态的 TypeScript 计算环境。
|
|
|
29
29
|
|
|
30
30
|
## 快速开始
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
需要最新可用的官方 DSH;Node.js 需同时满足插件的 `^22.19.0 || >=24.0.0` 与所选 DSH 的运行要求:
|
|
33
33
|
|
|
34
34
|
```sh
|
|
35
35
|
dsh plugin --profile <profile> add dsh-ptc-plus
|
|
@@ -37,7 +37,7 @@ dsh plugin --profile <profile> add dsh-ptc-plus
|
|
|
37
37
|
|
|
38
38
|
把 `<profile>` 换成实际 profile 名称,重启 DSH,在会话中选择 **PTC 模式**。连续计算、调用容错和全局绑定默认开启;升级用 `dsh plugin --profile <profile> add dsh-ptc-plus@latest` 再重启宿主,其他安装方式、Desktop、本地开发启动器和故障排查见[安装指南](docs/installation.md)。
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
插件声明 DSH 兼容范围 `>=0.2.1-0 <0.2.3`,由宿主执行版本预检;范围内的接口适配仍通过公共能力检查与打包测试验证。
|
|
41
41
|
|
|
42
42
|
界面默认显示会话里的 **REPL** 页签,宽屏顶部还有 **PTC Plus** 标志。输入框旁的星光按钮打开全局绑定菜单、会话能力工作台和 **PTC Plus 设置**,侧边栏的 **插件 → 已安装 → dsh-ptc-plus → 配置** 是同一套设置。
|
|
43
43
|
|
|
@@ -88,7 +88,7 @@ return total() // 20
|
|
|
88
88
|
- 已有闭包读到更新后的绑定,提前保存的函数值仍是原来的函数;不同块、函数和循环迭代的作用域照常区分。
|
|
89
89
|
- 声明初始化失败不会永久占住这个名称,失败前已经生效的修改也不会回滚。
|
|
90
90
|
|
|
91
|
-
cell 支持 TypeScript(含运行时 `enum` 和 `namespace`)、顶层 `await` / `return` 和静态 `import` / `export`;静态导入在整个 cell
|
|
91
|
+
cell 支持 TypeScript(含运行时 `enum` 和 `namespace`)、顶层 `await` / `return` 和静态 `import` / `export`;静态导入在整个 cell 正文执行前生效,正文里的赋值随后可以覆盖它。设置中的“绑定更新语义”直接显示当前策略,可选择“允许重声明和覆盖”(`stateful`)或“启用名称保护”(`protected`);`tools` 这类受保护的运行时名称任何时候都不能覆盖。
|
|
92
92
|
|
|
93
93
|
`run_code`、编辑后的代码和全局绑定工作台采用同一套语言策略;显式 `eval`、`Function`、`node:vm` 或独立运行时仍受各自的原生边界约束。作用域、模块互操作和历史会话规则见[语言参考](docs/runtime-reference.md#cell-semantics),完整的语言规则、配置字段与诊断见[运行时参考](docs/runtime-reference.md)。
|
|
94
94
|
|
|
@@ -180,7 +180,9 @@ return capabilities.search({ query: 'read file content', budgetBytes: 8192 })
|
|
|
180
180
|
|
|
181
181
|
在插件 graph IPC 支持的值范围内,程序参数、结果和恢复记录能保留 `undefined`、BigInt、`NaN`、无穷大、稀疏数组、循环引用和共享引用关系,支持的值直接返回即可,不必自己写 `JSON.stringify`(它会丢掉对象里的 `undefined`,把 `NaN` 和无穷大变成 `null`、把 `-0` 变成 `0`,还会拒绝 BigInt)。函数、Promise、类实例、Date、Map、Set 不在这个范围内,原生 `tools.*` 的 JSON 参数与结果契约也不受影响,详见[值契约](docs/value-wire.md)。
|
|
182
182
|
|
|
183
|
-
|
|
183
|
+
会话状态不是永久内存:重启或上下文压缩后,只保留能从会话记录验证、且来源仍在模型上下文中的状态,其余会被丢弃并给出提示,必要时从空环境继续当前计算。会话记录本身缺失或损坏时会明确报错,不会被当作成功恢复的空会话。恢复不会重新派发已记录的原生工具调用,也不会撤销历史外部效果,依据和限制见[运行时参考](docs/runtime-reference.md)。
|
|
184
|
+
|
|
185
|
+
宿主显式重置程序环境时,会清除会话变量、命名 checkpoint 和可编辑目标;重启或 fork 后也不会恢复重置前的状态。已完成的外部操作保留,全局绑定配置保持有效。
|
|
184
186
|
|
|
185
187
|
停止后台子代理不会清空父会话的 REPL 状态;通知触发的后续调用可以继续使用父会话的变量。父会话自身释放后,后续调用仍按上述恢复规则继续计算。
|
|
186
188
|
|
|
@@ -194,6 +196,8 @@ PTC Plus 是社区插件,与 DeepSeek 或 DSH 无隶属或背书关系。
|
|
|
194
196
|
|
|
195
197
|
## 开发
|
|
196
198
|
|
|
199
|
+
Windows 可双击 `scripts\run-dev-dsh.cmd` 启动隔离开发环境;默认复用经 Windows Node.js 实测可监听的端口,缓存端口被占用或拒绝访问时自动更换。手动指定的端口保持原值,详见[安装指南](docs/installation.md)。
|
|
200
|
+
|
|
197
201
|
开发在仓库根目录进行:`npm ci` 安装依赖,`npm run build` 重新生成 `client.cjs` 和 compiler 产物。聚焦测试必须指定用例:
|
|
198
202
|
|
|
199
203
|
```sh
|
package/client.cjs
CHANGED
|
@@ -1965,8 +1965,8 @@ var CONFIG_FIELDS = Object.freeze([
|
|
|
1965
1965
|
type: "enum",
|
|
1966
1966
|
options: Object.freeze(["stateful", "protected"]),
|
|
1967
1967
|
default: "stateful",
|
|
1968
|
-
label: "\
|
|
1969
|
-
labelEn: "
|
|
1968
|
+
label: "\u7ED1\u5B9A\u66F4\u65B0\u8BED\u4E49",
|
|
1969
|
+
labelEn: "Binding update semantics",
|
|
1970
1970
|
description: "\u540C\u4E00\u4F5C\u7528\u57DF\u7684\u58F0\u660E\u548C\u8D4B\u503C\u53EF\u66F4\u65B0\u53D8\u91CF\u3001\u51FD\u6570\u3001\u7C7B\u53CA\u5BFC\u5165\u3002\u9009\u201C\u542F\u7528\u540D\u79F0\u4FDD\u62A4\u201D\u65F6\u6539\u4E3A\u68C0\u6D4B\u8DE8 cell \u91CD\u58F0\u660E\uFF0C\u5E76\u4FDD\u62A4\u65B0\u5EFA\u7684 const \u548C import\uFF1B\u9759\u6001 import/export \u59CB\u7EC8\u53EF\u7528\u3002",
|
|
1971
1971
|
descriptionEn: "Declarations and assignments update variables, functions, classes and imports in the same scope. With \u201CProtect names\u201D selected, cross-cell redeclarations are detected instead and newly created const and import bindings are protected; static import/export remains available."
|
|
1972
1972
|
},
|
|
@@ -2401,6 +2401,12 @@ var CONFIG_DEFAULTS = Object.freeze(
|
|
|
2401
2401
|
Object.fromEntries(CONFIG_FIELDS.map((field) => [field.key, field.default]))
|
|
2402
2402
|
);
|
|
2403
2403
|
|
|
2404
|
+
// internal/message-sources.js
|
|
2405
|
+
var PTC_MESSAGE_SOURCE_KIND = "plugin:ptc-plus";
|
|
2406
|
+
function isPtcMessageSource(source) {
|
|
2407
|
+
return source?.kind === PTC_MESSAGE_SOURCE_KIND || source?.kind === "plugin" && source.plugin === "ptc-plus";
|
|
2408
|
+
}
|
|
2409
|
+
|
|
2404
2410
|
// internal/session-journal-schema.js
|
|
2405
2411
|
var IMPORT_BOUNDARY_JOURNAL_VERSION = 7;
|
|
2406
2412
|
var PER_NAME_USER_BINDINGS_JOURNAL_VERSION = 8;
|
|
@@ -2501,6 +2507,7 @@ function normalizeJournalUserBindingNames(journal) {
|
|
|
2501
2507
|
return normalizeUserBindingNames(journal.userBindingNames);
|
|
2502
2508
|
}
|
|
2503
2509
|
var RECOVERY_BOUNDARY_FIELDS = /* @__PURE__ */ new Set(["failedCallSeq", "frontierCallSeq"]);
|
|
2510
|
+
var RESET_RECOVERY_BOUNDARY_FIELDS = /* @__PURE__ */ new Set(["failedResetSeq", "frontierCallSeq"]);
|
|
2504
2511
|
var REWRITE_FIELDS = /* @__PURE__ */ new Set(["kind", "description", "source"]);
|
|
2505
2512
|
var REWRITE_KINDS = /* @__PURE__ */ new Set(["import", "redeclaration", "export"]);
|
|
2506
2513
|
|
|
@@ -2827,7 +2834,7 @@ function isValidDerivedRun(value) {
|
|
|
2827
2834
|
}
|
|
2828
2835
|
function isValidRecoveryBoundaries(value) {
|
|
2829
2836
|
try {
|
|
2830
|
-
return Array.isArray(value) && value.every((boundary) => hasExactFields(boundary, RECOVERY_BOUNDARY_FIELDS) && isSafeSequence(boundary.failedCallSeq) && (boundary.frontierCallSeq === null || isSafeSequence(boundary.frontierCallSeq)));
|
|
2837
|
+
return Array.isArray(value) && value.every((boundary) => hasExactFields(boundary, RESET_RECOVERY_BOUNDARY_FIELDS) && isSafeSequence(boundary.failedResetSeq) && boundary.frontierCallSeq === null || hasExactFields(boundary, RECOVERY_BOUNDARY_FIELDS) && isSafeSequence(boundary.failedCallSeq) && (boundary.frontierCallSeq === null || isSafeSequence(boundary.frontierCallSeq)));
|
|
2831
2838
|
} catch {
|
|
2832
2839
|
return false;
|
|
2833
2840
|
}
|
|
@@ -12902,17 +12909,6 @@ function createPtcSettingsView(React32, deps) {
|
|
|
12902
12909
|
onChange: (event) => onChange(field, event.target.checked)
|
|
12903
12910
|
});
|
|
12904
12911
|
}
|
|
12905
|
-
if (field.type === "enum") {
|
|
12906
|
-
return h("input", {
|
|
12907
|
-
type: "checkbox",
|
|
12908
|
-
role: "switch",
|
|
12909
|
-
className: "ptcPlusCheck",
|
|
12910
|
-
checked: value !== "protected",
|
|
12911
|
-
disabled,
|
|
12912
|
-
"aria-label": label,
|
|
12913
|
-
onChange: (event) => onChange(field, event.target.checked ? "stateful" : "protected")
|
|
12914
|
-
});
|
|
12915
|
-
}
|
|
12916
12912
|
return h("input", {
|
|
12917
12913
|
type: "number",
|
|
12918
12914
|
className: "ptcPlusInput",
|
|
@@ -13214,12 +13210,12 @@ function createPtcSettingsView(React32, deps) {
|
|
|
13214
13210
|
t2(migratingPolicy ? "bindingPolicy.migrationDescription" : `${field.key}.description`)
|
|
13215
13211
|
)
|
|
13216
13212
|
),
|
|
13217
|
-
|
|
13218
|
-
value: "legacy",
|
|
13213
|
+
field.type === "enum" ? h(Select2, {
|
|
13214
|
+
value: migratingPolicy ? "legacy" : value[field.key],
|
|
13219
13215
|
disabled: fieldDisabled(field),
|
|
13220
13216
|
label: t2(`${field.key}.label`),
|
|
13221
13217
|
options: [
|
|
13222
|
-
{ value: "legacy", label: t2("bindingPolicy.legacy"), disabled: true },
|
|
13218
|
+
...migratingPolicy ? [{ value: "legacy", label: t2("bindingPolicy.legacy"), disabled: true }] : [],
|
|
13223
13219
|
...field.options.map((policy) => ({ value: policy, label: t2(`bindingPolicy.${policy}`) }))
|
|
13224
13220
|
],
|
|
13225
13221
|
onChange: (next) => persist(field, next)
|
|
@@ -13993,12 +13989,6 @@ function createReplView(React32, deps) {
|
|
|
13993
13989
|
return { ReplComposer, ReplConsole, ReplMemoryCard, replPopoverIsOpen, placeReplPopover, useObservedReplMemory };
|
|
13994
13990
|
}
|
|
13995
13991
|
|
|
13996
|
-
// internal/message-sources.js
|
|
13997
|
-
var PTC_MESSAGE_SOURCE_KIND = "plugin:ptc-plus";
|
|
13998
|
-
function isPtcMessageSource(source) {
|
|
13999
|
-
return source?.kind === PTC_MESSAGE_SOURCE_KIND || source?.kind === "plugin" && source.plugin === "ptc-plus";
|
|
14000
|
-
}
|
|
14001
|
-
|
|
14002
13992
|
// internal/compiler-descriptors.js
|
|
14003
13993
|
function createCompilerDescriptors(object, reflect) {
|
|
14004
13994
|
const define = object.defineProperty, defineMany = object.defineProperties;
|
|
@@ -19,9 +19,9 @@ The editor captures the most recent eligible cell at the persisted `tool/ptc-dis
|
|
|
19
19
|
|
|
20
20
|
The editor accepts exactly one `edits` or `regex_edits` array. Exact edits require unique nonempty `old_string` matches. Each regex edit requires `pattern`, `flags`, `replacement` and `expected_matches`; replacement uses JavaScript `$1`, `$<name>` and `$$` syntax. At most 16 nonoverlapping edits are applied atomically. `internal/rejected-cell-editor.js` owns matching, expansion and CPU/source budgets.
|
|
21
21
|
|
|
22
|
-
For an accepted edit, the nested SDK call returns `{ accepted: true, scheduled: true, target_call_seq }`. This is an acceptance receipt, not the revised computation's value or an idempotence promise. The current outer cell continues with its existing state and original return value or error. After that cell releases its worker, but before its top-level `run_code` result settles, PTC Plus dispatches the complete revised source through DSH's
|
|
22
|
+
For an accepted edit, the nested SDK call returns `{ accepted: true, scheduled: true, target_call_seq }`. This is an acceptance receipt, not the revised computation's value or an idempotence promise. The current outer cell continues with its existing state and original return value or error. After that cell releases its worker, but before its top-level `run_code` result settles, PTC Plus dispatches the complete revised source through DSH's public invocation pipeline. Registry Hosts accept the execution input through `tools.execute`; executor Hosts use the published `@deepseek-ai/dsh-tools/pipeline` `ToolExecutionPipeline.prepare`, `dispatch` and `complete` stages with the selected live transport definition. The invocation retains the actual root token as `parent`, the original `rootCallId` and the root's step admission. The Host still owns validation, policy, cancellation and final result materialization; a root model-call batch cannot carry this nested relation. The root result retains that outer canonical value or error and forwards the derived result's Host-rendered content, images, additional contexts and, for a successful root result, turn-conclusion flag. The definition-owned `projectContent` callback is installed before dispatch starts, so derived content reaches root post-policy; `exec.deferContext` and `exec.concludeTurn` carry contexts and the successful root conclusion. Root policy may replace or block that presentation. The runtime bridge preserves existing callbacks and their property descriptors, restores only its own installed callbacks on disposal, and unwinds partial installation on failure. The next cell sees the revised bindings. A nested receipt rejected or changed before acceptance prevents dispatch; cancellation or disposal before dispatch does likewise. Removal of the final root metadata after a derived run has executed invalidates recovery evidence but cannot undo its effects.
|
|
23
23
|
|
|
24
|
-
The model-authored outer `run_code` remains the sole top-level call in assistant history. Official nested events retain the editor's real name, arguments and settled receipt. The plugin records its actual derived
|
|
24
|
+
The model-authored outer `run_code` remains the sole top-level call in assistant history. Official nested events retain the editor's real name, arguments and settled receipt. The plugin records its actual derived Host invocation through public `Session.append`: the start carries losslessly detached arguments, a distinct sub-call identity, the original root ID and that still-running root's ID as its parent. The actual execution uses the root's real token as `parent`. Its settled event records the canonical error status and metadata; rendered content passes through the public scoped `tools/ptc-dispatch-log` waterfall with the real root execution. A throwing log projector falls back to the original settled content. These records describe actual executions and do not invent an assistant call, parent or completion. Recovery proves exactly one start and one later settlement for each editor and actual derived sub-call identity within its root-call/final-result window. A metadata start sequence alone cannot resolve duplicate dispatch identities; settled ID reuse outside that window remains independent.
|
|
25
25
|
|
|
26
26
|
If the public Host never invokes `presentationMeta` for this owned nested success, the bridge may capture its canonical frozen value and tentative settlement through the read-only pre-policy `projectContent` callback. Private evidence is admissible only for the exact execution token, session, parent and continuation, with no initial plugin journal, no subsequent projector call, unchanged base metadata, final success and the same canonical value object. Host value replacement, block/error, missing capture or removal of already projected metadata rejects it. The sidecar supplies only the plugin-owned actual derived settlement and root relation; it never changes the Host result or restores pre-policy content. Final root metadata remains required. The proof comes from public canonical value identity and the before/after policy callbacks, without a Host version branch.
|
|
27
27
|
|
|
@@ -8,9 +8,9 @@ PTC Plus integrates with DSH services, request bindings, prompt assembly, sessio
|
|
|
8
8
|
|
|
9
9
|
PTC Plus must remain independently installable on unmodified official DSH distributions. Host source is read-only research evidence, not an implementation workspace for plugin features. Plugin changes must not patch host source or installed packages, introduce install-time host patches, or require a custom host build. Plugin-owned components, panels, styling, portals and public renderer replacements are valid UI choices within the consumed contracts; integration does not require every visual element or layout to be native. A locally invented extension declaration is not a published public capability. Choose among published surfaces according to the required user experience rather than assuming that a UI feature must become a historical message node. If none can satisfy the required behavior, record the actual limitation; do not substitute a custom distribution or present a compatibility fallback as delivery.
|
|
10
10
|
|
|
11
|
-
The compatibility target is the latest available DSH release.
|
|
11
|
+
The compatibility target is the latest available DSH release. The manifest declares a bounded `engines.dsh` range for DSH-owned installation and startup preflight. Runtime interface selection depends on public extension contracts and observed live schemas, never on a DSH version comparison. An upstream default projection is not an extension ceiling: when public scoped registration and presentation support a plugin-owned capability, PTC Plus preserves that capability and its model-visible identity instead of deleting or renaming it to match the default. Deterministic normalization remains valid for a call that is outside the declared direct surface when the live schema proves one native target and the lowering preserves arguments, call identity, authority, and result semantics. Deterministic tests exercise the consumed contracts; model-backed and packaging acceptance runners use the installed DSH and record `dsh --version` in generated reports so failures remain attributable without turning the observed value into policy. The manifest range, its lockfile counterpart, package-admission tests and user guidance may name DSH versions to state and verify the admission contract. Those declarations do not select runtime interface branches.
|
|
12
12
|
|
|
13
|
-
Release discovery is separated from candidate verification.
|
|
13
|
+
Release discovery is separated from candidate verification. Verification targets are expressed as channels; the manifest range separately bounds Host admission. `compat/channels.json` is generated from the official dist-tags and records, per channel, the resolved host release, the tarball integrity of every host package whose published surface the plugin probes, and whether that channel may block a release: `latest` (newest published release) and `next` (in-flight release candidate) block, while `alpha` (a pre-adaptation for a line the host has not released yet) only reports. A probe package the release does not publish is recorded with the version and integrity that release's own dependency range resolves to, so the channel still names the bytes an install receives; a probe package the release neither publishes nor depends on is recorded as absent, and the install proof rejects a graph that contains one. These records are reproducibility evidence selected by the channel declarations; they are not compatibility allowlists or runtime branches. `npm run host:channels:update` is the only way to refresh them and starts from the registry; ordinary `verify` and the full branch of `check` make no registry request and validate the tracked manifest offline. The root manifest declares the official `next` channel for the DSH packages used by development, and `host:channels:graph` moves the lock onto the release that channel resolves to; the scheduled channel workflow runs it in the same commit as a channel change. Ordinary gates read whichever graph the lock froze and never resolve a tag.
|
|
14
14
|
|
|
15
15
|
The scheduled channel refresh resolves every channel from its dist-tag. When a channel moves it commits the regenerated manifest on an automation-owned branch, opens or updates one pull request, and dispatches the normal CI workflow once for that candidate. GitHub suppresses workflow runs from branch and pull-request events produced by the workflow's `GITHUB_TOKEN`, so the explicit dispatch is the candidate's only CI run. If no channel moved, the refresh writes the identical document and nothing is committed. The Host contract suite installs each channel on demand from the manifest into an ignored cache, proves the installed versions against the manifest, packs the plugin, and runs the execution-seam, RPC-codec, compressed Session persistence, and pathless Cordis companion contracts through a repository-external consumer that exposes the selected Host's public packages. `npm run test:host-contract -- <channel>` selects one channel, and the default selection is the blocking set. CI runs one job per channel and lets the `alpha` job report without failing the workflow. No compatibility run independently selects tags for DSH service packages, because their dist-tags need not move as one cohort.
|
|
16
16
|
|
|
@@ -65,7 +65,7 @@ capability, storage and observation rules independently of transport.
|
|
|
65
65
|
|
|
66
66
|
**Pin one verified DSH release.** A pin makes one historical environment reproducible but turns normal upstream progress into an artificial incompatibility and allows the implementation to drift from the release users actually install.
|
|
67
67
|
|
|
68
|
-
**
|
|
68
|
+
**Leave manifest admission unrestricted.** A wildcard admits Host versions beyond the compatibility boundary the package declares to users. The package therefore retains a bounded `engines.dsh` range, while capability checks select runtime interfaces. A range is an admission contract, not proof that every matching release has passed testing. Updating a Host within the range does not justify removing its bounds; moving a bound requires an explicit compatibility decision and relevant Host evidence. The packed contract suite runs the selected Host's public `evaluatePluginCompatibility` before importing plugin code; required service peers still establish package resolution.
|
|
69
69
|
|
|
70
70
|
**Treat the upstream default tool projection as an immutable plugin limit.** This avoids scoped presentation work, but discards capabilities that the public registry supports and can force valid model calls through lossy aliases. Defaults describe the host's built-in product choice; public extension contracts define what a plugin may add. Invalid out-of-surface calls may still be normalized when their intended native target is provable.
|
|
71
71
|
|
|
@@ -75,4 +75,4 @@ capability, storage and observation rules independently of transport.
|
|
|
75
75
|
|
|
76
76
|
Feature completion requires evidence from the actual packaged plugin running on the selected unmodified Host, including the affected user flow. Component fixtures and public-interface unit tests validate narrower properties; they do not prove that a required renderer exists or is loaded in that distribution. A clean code review and passing deterministic checks are separate from product acceptance. Both must cover the final change before a feature is described as delivered; commit and publish authorization remain separate user decisions.
|
|
77
77
|
|
|
78
|
-
Each upstream DSH release becomes the immediate compatibility target and must pass the public-surface, packaging, and model-backed checks appropriate to the change. The automated pull request makes an upstream tag movement an explicit source candidate; the lockfile and CI result keep its proof reproducible after the registry moves again.
|
|
78
|
+
Each upstream DSH release becomes the immediate compatibility target and must pass the public-surface, packaging, and model-backed checks appropriate to the change. The automated pull request makes an upstream tag movement an explicit source candidate; the lockfile and CI result keep its proof reproducible after the registry moves again. When a new target falls outside the declared range, its admission bounds must be reviewed and updated with the relevant evidence before claiming support. Historical reports remain attributable through generated runtime metadata or source comments, while a passing older run never substitutes for validation against the latest release.
|
|
@@ -8,15 +8,15 @@ Accepted
|
|
|
8
8
|
|
|
9
9
|
## Context
|
|
10
10
|
|
|
11
|
-
DSH's shipped 创造模式 composes `@deepseek-ai/dsh-tool-cordis` and
|
|
11
|
+
DSH's shipped 创造模式 composes `@deepseek-ai/dsh-tool-cordis` and its official companion Skill (`dsh-doc`, historically `cordis-plugin-development`) into its native `cordis` preset. PTC users may also need that complete official authoring workflow without leaving PTC mode, but adding it unconditionally would enlarge a high-authority tool surface and add stable schema/prompt cost to every request. PTC Plus must not copy DSH's Cordis implementation or Skill content, or turn this choice into another preset system.
|
|
12
12
|
|
|
13
13
|
Tool registration must finish before the prompt assembly returned to the agent; otherwise the first request lacks Cordis schemas and guidance. DSH's synchronous `agent/created` lifecycle and agent context provide the publication point and owner, but child-fiber readiness can still overlap the first provider snapshot.
|
|
14
14
|
|
|
15
15
|
## Decision
|
|
16
16
|
|
|
17
|
-
Add `cordisToolsEnabled: boolean`, default `false`, as a live PTC Plus setting. When enabled, PTC Plus mounts the official `@deepseek-ai/dsh-tool-cordis` plugin and a maintained `@deepseek-ai/dsh-skill-filesystem` provider in each agent scope that exposes every surface the mount publishes through: `run_code`, the `skill` tool, and the public `agentPresets` and `skills` services; disabling it disposes both fibers immediately. The provider resolves the shipped `cordis` preset through the public `agentPresets` service and reads its sibling `skills` root as an immutable bundled Host resource without including default roots or watching the packaged directory. At the public `skills.registerProvider` seam, PTC Plus transparently filters discovery and loading to exactly
|
|
17
|
+
Add `cordisToolsEnabled: boolean`, default `false`, as a live PTC Plus setting. When enabled, PTC Plus mounts the official `@deepseek-ai/dsh-tool-cordis` plugin and a maintained `@deepseek-ai/dsh-skill-filesystem` provider in each agent scope that exposes every surface the mount publishes through: `run_code`, the `skill` tool, and the public `agentPresets` and `skills` services; disabling it disposes both fibers immediately. The provider resolves the shipped `cordis` preset through the public `agentPresets` service and reads its sibling `skills` root as an immutable bundled Host resource without including default roots or watching the packaged directory. At the public `skills.registerProvider` seam, PTC Plus transparently filters discovery and loading to exactly the selected official companion identity; the maintained filesystem provider still owns parsing, resource bases, incomplete observations, and body loading. This prevents unrelated or obsolete sibling Skills from silently enlarging the PTC surface without copying the companion content or switching the current preset. A scope that omits one of those surfaces is not an error: the owner keeps the agent pending, publishes nothing there, and retries on the DSH tools-change signal or the next prompt assembly, because a later registration or provided service can supply the missing member ([ADR 0029](0029-keep-plugin-unavailability-out-of-the-host-agent-lifecycle.md)).
|
|
18
18
|
|
|
19
|
-
The Skill provider and official Cordis child fiber form one reversible mount. Both must settle, and the scoped `skills` service must prove that
|
|
19
|
+
The Skill provider and official Cordis child fiber form one reversible mount. Both must settle, and the scoped `skills` service must prove that the selected companion resolves from the added provider as model-invocable and loadable, before the first prompt assembly is returned. A prepended public `system-prompt/assemble` waterfall listener is the final race barrier: if collection began before the mount settled, it waits for readiness, discards that stale assembly, and invokes public assembly again so DSH recollects the official providers. It does not synthesize or mutate Cordis schemas or guidance. The Cordis fiber's resolved `inject` declaration is the authoritative required-service list, and its live registrations are the authoritative tool names, schemas, and guidance. A scope whose exposed preset, Skill service/tool, declared service, publication, or child fiber contradicts the DSH contract is a configuration error and rolls back every contribution; an absent surface only defers the mount. An unusable scope reached through the host's own calls — `agent/created` and the prepended waterfall — withdraws and reports one warning instead of failing the host operation that created the scope ([ADR 0029](0029-keep-plugin-unavailability-out-of-the-host-agent-lifecycle.md)).
|
|
20
20
|
|
|
21
21
|
The official plugin also registers Host inspect providers in the process-global `cordisInspect` service. Per-agent fibers therefore acquire owner-scoped leases for identical provider manifests instead of registering the same provider ID independently. Queries delegate to a registration from a still-live official fiber, and the process-global provider is removed when the final lease is released. A manifest mismatch remains a configuration error rather than silently choosing one contract.
|
|
22
22
|
|
|
@@ -24,17 +24,23 @@ Cordis tools remain native program bindings under `tools.*`. The PTC code-only d
|
|
|
24
24
|
|
|
25
25
|
Cordis definitions and Runs are process-local, while PTC journals replay every settled program binding as a recorded value without redispatch. On the first prompt for an agent or a new Cordis enable generation, PTC Plus derives whether normalized journals contain a Cordis transcript. If they do, it emits the fixed `tools:ptc-plus-cordis-recovery` runtime context: recorded values remain journal data, but the model must perform a live read-only Cordis Inspect before relying on prior IDs, state, approvals, or capability observations. The context remains until a newly settled successful `cordis_inspect*` call appears in the session log. It neither asserts that live state was lost nor reruns a mutating call.
|
|
26
26
|
|
|
27
|
-
Companion Skill resolution is capability-based. A generation that publishes an absolute composition path for the shipped `cordis` preset uses its sibling `skills` root. For a pathless generation, PTC Plus asks the Host's public `pluginPackages.packageOf` service for the active installation's `@deepseek-ai/dsh-agent-preset` or `@deepseek-ai/dsh-agent-presets` resource, then selects that generation's known Skill layout. Each resolution reads the current service after preset resolution; owner creation does not fix later mounts to an earlier service or its absence. Older generations that do not publish `pluginPackages` may resolve only the historical plural package from the Host's `ctx.baseUrl`; this compatibility path is disabled whenever the service exists, including when it returns no package. It never uses plugin-anchored ambient Node lookup, because a profile or Desktop installation may contain a stale package from another Host generation. PTC Plus
|
|
27
|
+
Companion Skill resolution is capability-based. A generation that publishes an absolute composition path for the shipped `cordis` preset uses its sibling `skills` root. For a pathless generation, PTC Plus asks the Host's public `pluginPackages.packageOf` service for the active installation's `@deepseek-ai/dsh-agent-preset` or `@deepseek-ai/dsh-agent-presets` resource, then selects that generation's known Skill layout. Each resolution reads the current service after preset resolution; owner creation does not fix later mounts to an earlier service or its absence. Older generations that do not publish `pluginPackages` may resolve only the historical plural package from the Host's `ctx.baseUrl`; this compatibility path is disabled whenever the service exists, including when it returns no package. It never uses plugin-anchored ambient Node lookup, because a profile or Desktop installation may contain a stale package from another Host generation. PTC Plus selects `dsh-doc/SKILL.md` when present, otherwise the historical `cordis-plugin-development/SKILL.md`, and carries the selected name together with its resource root through discovery, loading and readiness. It preserves the official identity and relative resource base, publishes only that Skill, and never selects by Host version. A package name or directory alone does not prove a supported resource. An unusable preset (`broken`) is reported as unavailable before path or package resolution, while an invalid published path remains a host contradiction rather than falling through to a different generation.
|
|
28
28
|
|
|
29
|
-
## Alternatives
|
|
29
|
+
## Alternatives considered
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
31
|
+
**Add the Cordis row to the PTC preset.** PTC Plus is installed as a host plugin and does not own or fork DSH's shipped preset files; a plugin setting keeps the optional mount within the plugin's ownership boundary.
|
|
32
|
+
|
|
33
|
+
**Register Cordis tools during `system-prompt/assemble` and continue with the existing assembly.** Provider and schema collection has already happened, so waiting alone would still omit the tools. The selected barrier instead discards that stale snapshot and asks DSH's public assembler to recollect after the owner-controlled mount is ready.
|
|
34
|
+
|
|
35
|
+
**Copy the tool definitions or their current names.** DSH owns their schemas, guidance, lifecycle, authority, and compatibility. Even a names-only completeness list would drift when DSH evolves and create a second contract.
|
|
36
|
+
|
|
37
|
+
**Enable the tools by default.** The tools can execute model-written plugins against the live runtime and carry a fixed schema cost. That trust and context expansion must be explicit.
|
|
38
|
+
|
|
39
|
+
**Mount one global Cordis tool fiber and hide it from native agents.** Its prompt hook and `@pluginId` context listener would remain global even if tool schemas were restricted, so unrelated agents would inherit behavior they did not enable.
|
|
40
|
+
|
|
41
|
+
**Copy `SKILL.md` into PTC Plus or add the Cordis preset's directory to global Skill roots.** Copied instructions drift, while a global root leaks the optional workflow into agents that did not enable it.
|
|
42
|
+
|
|
43
|
+
**Publish the complete preset-local Skill directory.** Directory membership is not the PTC feature contract; unrelated sibling additions would silently change the model surface and may target a different authoring workflow or tool generation.
|
|
38
44
|
|
|
39
45
|
## Consequences
|
|
40
46
|
|
|
@@ -12,6 +12,8 @@ DSH added an opt-in official Node execution mode (`executionMode: persistent-in-
|
|
|
12
12
|
|
|
13
13
|
Cells executed under the official mode produce no plugin journal records. They are an unrecorded execution interval: recovery never replays them, and they do not extend plugin state as recovery evidence.
|
|
14
14
|
|
|
15
|
+
Explicit release of a live session environment additionally follows [ADR 0051](0051-persist-explicit-host-environment-resets.md): the plugin clears its own computation through a persisted reset boundary, while ordinary disposed-Agent cleanup keeps journal recovery. This supplements original-provider cleanup and leaves non-session delegation intact.
|
|
16
|
+
|
|
15
17
|
## Alternatives considered
|
|
16
18
|
|
|
17
19
|
**Gate on the DSH release or on reading the original row's `executionMode` configuration.** The mode is a live runtime capability and a configuration fact outside the plugin's public contract; the provider's own retention declaration is proof that its environment survives between runs, and on older generations that lack the declaration the retained source form is the only evidence they publish.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Persist Explicit Host Environment Resets
|
|
2
|
+
|
|
3
|
+
## Problem
|
|
4
|
+
|
|
5
|
+
DSH calls the retained provider's public `release(owner)` both for explicit program reset and during Agent scope cleanup. Releasing only the original provider leaves PTC Plus variables live. Releasing only the worker allows its journal to revive them. Treating ordinary Agent disposal as reset would instead destroy valid session recovery.
|
|
6
|
+
|
|
7
|
+
## Decision
|
|
8
|
+
|
|
9
|
+
The public execution seam routes release to its installed adapter and original provider, waits for both, and propagates their failures. The runtime bridge owns the Agent lifecycle distinction: a session Agent whose public Cordis scope fiber `uid` is `null` is being disposed and retains proven journal recovery; a live session Agent requests explicit reset. Non-session owners keep original-provider delegation. This uses public lifecycle state, never release numbers, turn signals or notification text.
|
|
10
|
+
|
|
11
|
+
`SessionRuntime.resetEnvironment` releases the session kernel, then appends a public `user/message` with `surfaceOp: "append"` and source `{ kind: "plugin:ptc-plus", form: "environment-reset", version: 1 }`. The structured source proves the boundary independently of human-readable wording. The message states the computation change; DSH separately owns reset cancellation, serialization, completion notification and failed-reset retry. Cleanup or append failure rejects release. Plugin code adds no reset scheduler or permission system.
|
|
12
|
+
|
|
13
|
+
The shared session timeline retains historical log facts but records the latest reset position. Recovery starts after that position; old bindings, named checkpoints and editor targets have no computation eligibility. New cells start empty and configured Global User Bindings initialize normally. Projection state version 16 refolds older caches, and checkpoint admission derives the reset from the same source facts. Persistence and fork keep this ordinary public message. Reset neither deletes historical records nor redispatches, reverses or proves idempotence of completed effects. It does not change JavaScript language generations, global binding configuration, or ordinary Agent recovery.
|
|
14
|
+
|
|
15
|
+
An absent or unsupported reset source version invalidates prior recovery evidence. Its recovery receipt uses the closed alternative `{ failedResetSeq, frontierCallSeq: null }`, distinct from a failed executable call's `{ failedCallSeq, frontierCallSeq }`. Recovery accepts that receipt only for the latest damaged reset preceding its carrier and the empty frontier. The carrier starts independent computation; subsequent cold recovery consumes the receipt rather than contracting the same damage again. Both sequence migration and Client evidence validation preserve the target distinction. A missing or invalid receipt continues to deny unproved recovery.
|
|
16
|
+
|
|
17
|
+
## Alternatives considered
|
|
18
|
+
|
|
19
|
+
**Only terminate the worker.** Cold replay restores its earlier state and contradicts the reset receipt.
|
|
20
|
+
|
|
21
|
+
**Reset on every provider release.** Agent teardown also releases retained environments. Treating that cleanup as explicit reset makes ordinary resume and fork lose valid computation.
|
|
22
|
+
|
|
23
|
+
**Use a custom raw session event or experimental plugin record.** The released persistence reader rejects unknown required event types; DSH reserves experimental plugin records for its own packages. A plugin-owned message uses the published external extension contract and remains model-visible.
|
|
24
|
+
|
|
25
|
+
**Recognize the Host's reset sentence.** Notification text and delayed injection are presentation, not durable computation identity. They cannot prove a reset before release returns.
|
|
26
|
+
|
|
27
|
+
## Consequences
|
|
28
|
+
|
|
29
|
+
An explicit reset survives persisted cold recovery and fork without reviving earlier state. The live provider and historical journal remain separate owners, and DSH retains control of reset coordination. A reset adds one plugin message describing its computation boundary alongside the Host's completion receipt. Downgrading to a plugin generation that predates this contract does not establish reset-aware recovery.
|
package/docs/adr/README.md
CHANGED
|
@@ -30,3 +30,4 @@ This directory records stable design constraints for PTC Plus. An ADR states a d
|
|
|
30
30
|
- [0048: Supersede A Rewritten Cell](0048-supersede-a-rewritten-cell.md) — an edit with the rewrite setting on supersedes its target; the target stays in the log and its names are reported as replaced.
|
|
31
31
|
- [0049: Prove A Settlement Against Its Published Record](0049-prove-a-settlement-against-its-published-record.md) — a settlement carries the digest of what it asserts, so an edited record is not evidence.
|
|
32
32
|
- [0050: Read And Write The Host Surface Only Through Its Published Contract](0050-read-host-surfaces-through-their-published-contract.md) — contracted executor readers, the call id a batch host echoes back, and owned slot descriptors that disposal restores.
|
|
33
|
+
- [0051: Persist Explicit Host Environment Resets](0051-persist-explicit-host-environment-resets.md) — public reset retires earlier computation durably while Agent disposal preserves recovery.
|
package/docs/architecture.md
CHANGED
|
@@ -23,7 +23,7 @@ DSH 的公开 presentation 为 `native` 或 `ptc`。agent composition owner、
|
|
|
23
23
|
|
|
24
24
|
`edit_run_code` 在持久化 `tool/ptc-dispatch-start` 处捕获当前 open turn 最近的可编辑 cell,按 root、parent、sub-call identity、参数与 sequence 校验正式事件。调查工具不擦除目标,后来的 settlement 不追溯改变它。调用必须且只能提交 `edits` 或 `regex_edits` 之一,并可携带 `expected_target_call_seq`;目标前置条件不一致时不派生执行。`internal/rejected-cell-editor.js` 统一拥有 schema、匹配、JavaScript replacement 语义、预算和原子源码物化。
|
|
25
25
|
|
|
26
|
-
接受收据为 `{ accepted: true, scheduled: true, target_call_seq }`,拒绝为 `{ accepted: false, scheduled: false, reason }`。接受只表示待执行:外层 cell 的后续语句仍使用当前状态,保留其 canonical return 或 error。外层 worker 结束后、根结果结算前,runtime bridge 通过 DSH
|
|
26
|
+
接受收据为 `{ accepted: true, scheduled: true, target_call_seq }`,拒绝为 `{ accepted: false, scheduled: false, reason }`。接受只表示待执行:外层 cell 的后续语句仍使用当前状态,保留其 canonical return 或 error。外层 worker 结束后、根结果结算前,runtime bridge 通过 DSH 公共调用流水线执行完整修订源码:registry 宿主使用 `tools.execute()`,executor 宿主使用已发布的 `ToolExecutionPipeline.prepare/dispatch/complete`,保留原 `rootCallId`、真实 parent token 与根调用的 step admission,并通过调用开始前已安装的公开 `projectContent` 将派生 content、images 送入根 post-policy;`exec.deferContext` 与 `exec.concludeTurn` 转发 additionalContexts 和成功根结果的 concludesTurn。成功根结果保留 Host canonical 对象,避免重新投影丢失 journal;根 policy 仍可替换或阻断这些展示内容。 runtime bridge 保留原有 callback 与 property descriptor;安装失败时撤回已安装部分,卸载时只恢复自己仍拥有的 callback。普通外层计算失败不撤销已接受编辑;取消、lease 结束或 disposal 阻止未开始的派生执行。同一根 cell 至多接受一次编辑,派生执行不能重新取得根编辑资格。
|
|
27
27
|
|
|
28
28
|
assistant history 保留原始根 `run_code`,正式 nested events 保留 editor 的名称、delta 参数与收据。插件通过公开 `Session.append` 记录真实派生 `run_code` 的 start/settle,实际执行的 parent token 与事件 parent 都来自仍在运行的根 transport;公开 scoped `tools/ptc-dispatch-log` 使用真实根 execution 留存内容。根结果私有 `dshPtcPlusPostEdit` 记录完整派生源码、journal、目标、editor 的 `startSeq` 与实际执行的 `executionStartSeq`;不虚构 assistant call、父调用或结算。最终 metadata 丢失不能撤销已发生效果,只使未证明状态丧失恢复资格。恢复 owner 校验根 journal 的收据、editor 和派生执行的正式 dispatch pairs、canonical 结算事实、目标变换与根/目标双重模型可见来源,按实际 root 后 derived 顺序恢复状态;cold replay 返回 recorded binding 值,不重新派发 editor 或外部效果。成功修订成为下一编辑目标。历史顶层 editor metadata 继续由其原有 generation 校验。详见 [ADR 0005](adr/0005-temporary-rejected-cell-edit-transport.md)。
|
|
29
29
|
|
|
@@ -56,9 +56,9 @@ Client half 在侧栏 **插件 → 已安装 → dsh-ptc-plus** 的插件行配
|
|
|
56
56
|
|
|
57
57
|
`bindingUpdates` 是新配置的统一入口,默认 `stateful`,也可选择 `protected`。Host schema 保留该字段原始缺省状态,再由 `runtime-config.js` 把完整旧策略映射到相应新策略;混合旧开关保留显式 `legacyBindingSettings` 兼容态。Client 复用同一 resolver,仅在兼容态展示旧开关;用户选择统一开关时,一次 settings update 同时写入新策略并清除兼容标记。
|
|
58
58
|
|
|
59
|
-
`cordisToolsEnabled` 默认关闭且即时生效。Host 只在同时暴露 `run_code`、`skill` 工具与 `agentPresets`/`skills` service 的 agent scope 中挂载官方 `@deepseek-ai/dsh-tool-cordis`,并通过公共 `agentPresets` service 定位 shipped `cordis` preset,再用维护中的 Skill filesystem plugin 把其 companion Skill 目录发布到同一 scope。两个 child fiber、tool guidance
|
|
59
|
+
`cordisToolsEnabled` 默认关闭且即时生效。Host 只在同时暴露 `run_code`、`skill` 工具与 `agentPresets`/`skills` service 的 agent scope 中挂载官方 `@deepseek-ai/dsh-tool-cordis`,并通过公共 `agentPresets` service 定位 shipped `cordis` preset,再用维护中的 Skill filesystem plugin 把其 companion Skill 目录发布到同一 scope。两个 child fiber、tool guidance 与选中的官方 companion Skill 是一个 mount;首轮 request 等待完整发布和 scoped Skill load 验证,关闭、agent/runtime 释放或任一激活失败时逆序卸载。缺少其中任一 surface 的 scope 不是错误:owner 保持 pending、不在该 scope 发布内容,并在工具 surface 变化或下一次 prompt assembly 时重试;由宿主自身调用触达的不可用 scope 只从该 scope 撤出并记一条 warning,不使 `agents.create()` 或 prompt assembly 失败([ADR 0029](adr/0029-keep-plugin-unavailability-out-of-the-host-agent-lifecycle.md))。工具名、数量、schema 和 guidance 直接来自 official tool fiber,Skill 内容直接来自 shipped preset,Host 均不复制。官方插件同时向 process-global `cordisInspect` 注册 Host provider;owner 将 manifest 相同的 per-agent 注册合并为引用计数 lease,查询委托给当前仍存活的官方 registration,最后一份 lease 释放后才注销 provider。manifest 不一致时启用失败。该开关不切换 preset,也不改变 code-only direct-tool projection。
|
|
60
60
|
|
|
61
|
-
Skill 根在当前 generation 发布绝对 composition path 时取其 sibling;pathless generation 改由 active Host 的公共 `pluginPackages.packageOf` service 定位该安装的官方单数或复数 preset package resource。完全没有该 service 的旧 generation 仅可从 Host `ctx.baseUrl` 解析历史复数包;service 已存在但返回空或无效结果时不进入兼容路径,因此不会读取插件 profile 周围可能属于另一宿主的 ambient package
|
|
61
|
+
Skill 根在当前 generation 发布绝对 composition path 时取其 sibling;pathless generation 改由 active Host 的公共 `pluginPackages.packageOf` service 定位该安装的官方单数或复数 preset package resource。完全没有该 service 的旧 generation 仅可从 Host `ctx.baseUrl` 解析历史复数包;service 已存在但返回空或无效结果时不进入兼容路径,因此不会读取插件 profile 周围可能属于另一宿主的 ambient package。资源根中优先选择 `dsh-doc/SKILL.md`,否则选择旧 `cordis-plugin-development/SKILL.md`,名称与根路径一起贯穿 provider 过滤、加载和就绪验证;两者均缺失时拒绝 mount。已发布但无效的 path 不回退到另一 generation 的 package layout。
|
|
62
62
|
|
|
63
63
|
## Global User Bindings
|
|
64
64
|
|
|
@@ -38,6 +38,16 @@ PTC Plus 的正确承诺是:
|
|
|
38
38
|
|
|
39
39
|
这避免了两个错误极端:既不为追求恢复而删除正常 REPL 能力,也不把无法迁移的 heap 伪装成可确定重建。
|
|
40
40
|
|
|
41
|
+
## 显式环境重置
|
|
42
|
+
|
|
43
|
+
宿主对 live Agent 调用公共 `ptcRuntime.release(owner)` 时,runtime bridge 将其路由到 `SessionRuntime.resetEnvironment`。该路径先释放 live kernel,再通过公共 `Session.append` 写入插件自有 `user/message`,其结构化 source 为 `{ kind: "plugin:ptc-plus", form: "environment-reset", version: 1 }`,并用 `surfaceOp: "append"` 公开状态变化;清理或追加失败均向宿主返回失败,由宿主的 reset 协调器负责取消、等待和重试。插件不另建调度器;这条消息公开计算边界,宿主另行拥有 reset 完成回执。
|
|
44
|
+
|
|
45
|
+
共享 timeline 保留完整历史的关联事实,但以最新 reset 序号划定后续计算的起点:更早 cell、命名 checkpoint 和 edit target 不再有恢复资格;新的计算从空环境继续,并按配置重新初始化 Global User Bindings。`ptcPlusSessionLog` 状态版本 16 使旧缓存重新折叠日志;JSON checkpoint、冷恢复和 fork 都消费同一边界,不能用旧 restore 名称恢复重置前状态。重置不删除原始日志、不修改绑定配置、不撤销或重新派发历史外部效果。
|
|
46
|
+
|
|
47
|
+
历史 reset 的 `source.version` 缺失或不受支持时,恢复从空 frontier 继续当前计算,并在已确认结果写入 `{ failedResetSeq, frontierCallSeq: null }` 收缩记录。它只证明最新损坏 reset 到该 carrier 之间的恢复证据已被舍弃,不冒充失败的 executable call。后续冷恢复消费这份记录,保留 carrier 及其新分支,不重复收缩或派发外部调用;缺失或无效的记录仍不证明后续状态。
|
|
48
|
+
|
|
49
|
+
Agent scope 正常销毁时,Cordis 在调用清理 effect 前把其公共 fiber `uid` 置为 `null`。这种 release 只释放 live worker,保留可证明 journal 的冷恢复;它与用户显式重置不同。见 [ADR 0051](adr/0051-persist-explicit-host-environment-resets.md)。
|
|
50
|
+
|
|
41
51
|
## Journal
|
|
42
52
|
|
|
43
53
|
每个进入执行缝的 cell 创建 mutable tentative journal:
|
package/docs/installation.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Installation
|
|
2
2
|
|
|
3
|
-
PTC Plus requires Node.js `^22.19.0 || >=24.0.0` and targets the latest available DSH release with TypeScript PTC mode. Historical interface branches are retained through capability detection, without promising a fully verified earlier Host installation; when both generations expose competing presentation evidence, the current DSH contract wins.
|
|
3
|
+
PTC Plus requires Node.js `^22.19.0 || >=24.0.0` and targets the latest available DSH release with TypeScript PTC mode. The runtime must also meet the selected Host's own Node.js requirement, which may be stricter than the plugin's range. Historical interface branches are retained through capability detection, without promising a fully verified earlier Host installation; when both generations expose competing presentation evidence, the current DSH contract wins. DSH checks the declared compatibility range before loading the plugin; runtime interface selection follows those live extension surfaces.
|
|
4
4
|
|
|
5
|
-
The package declares `engines.dsh: "
|
|
5
|
+
The package declares `engines.dsh: ">=0.2.1-0 <0.2.3"` for DSH's plugin compatibility preflight. DSH evaluates that range, including prereleases, before loading the plugin. Public capability checks and packed Host contracts establish integration within the range; the declaration does not claim that every matching release has been tested. Host-owned service packages are peers of the plugin because the host supplies them; the PTC tool executor is an optional peer, because a host that keeps tool presentation in its registry does not publish that package at all.
|
|
6
6
|
|
|
7
|
-
The worker uses the Host's Node executable. Startup verifies native REPL framing, imports, syntax failures, synchronous throws, awaited rejections, and original return values. The adapter combines public eval callbacks with domain error events before REPL formatting; a source-end witness distinguishes empty completion from falsy rejection. A failed or timed-out probe reports a runtime prerequisite failure before user code executes. The engine range
|
|
7
|
+
The worker uses the Host's Node executable. Startup verifies native REPL framing, imports, syntax failures, synchronous throws, awaited rejections, and original return values. The adapter combines public eval callbacks with domain error events before REPL formatting; a source-end witness distinguishes empty completion from falsy rejection. A failed or timed-out probe reports a runtime prerequisite failure before user code executes. The plugin engine range and the Host's engine range are separate requirements; CI exercises Node 22.19, 24, and 26, without claiming that untested future releases have already passed.
|
|
8
8
|
|
|
9
9
|
Install the plugin into the profile that actually runs the target DSH surface. Do not assume a profile named `default` is active.
|
|
10
10
|
|
|
@@ -12,7 +12,7 @@ Install the plugin into the profile that actually runs the target DSH surface. D
|
|
|
12
12
|
|
|
13
13
|
| Component | Current contract |
|
|
14
14
|
| --- | --- |
|
|
15
|
-
| DeepSeek Harness |
|
|
15
|
+
| DeepSeek Harness | `engines.dsh: ">=0.2.1-0 <0.2.3"`; DSH owns version preflight, while live public extension checks and packed Host contracts establish integration |
|
|
16
16
|
| Runtime | DSH TypeScript PTC mode; cells currently accept modern JavaScript syntax |
|
|
17
17
|
| Node.js | `^22.19.0 || >=24.0.0` |
|
|
18
18
|
| Platforms | Windows CLI/Desktop and Linux CLI/Web verified locally; macOS package tests and import smoke run in CI, while live DSH integration and Desktop require release-time smoke testing |
|
|
@@ -20,7 +20,7 @@ Install the plugin into the profile that actually runs the target DSH surface. D
|
|
|
20
20
|
|
|
21
21
|
`danger-full-access` is the primary supported experience. The worker isolates the REPL lifecycle; it is not a malicious-code sandbox. DSH continues to own native-tool scope, policy, approval, cancellation, sandboxing, and scheduling. Narrower profiles expose only their available capabilities; PTC Plus does not simulate missing authority or add another permission system.
|
|
22
22
|
|
|
23
|
-
The optional `cordisToolsEnabled` integration requires the current DSH installation to provide its shipped `cordis` preset plus the public preset, Skill, Cordis, settings, and tool-runtime services. PTC Plus declares the shared service packages as unrestricted required peers instead of installing private runtime copies. For a pathless preset it asks the Host's `pluginPackages.packageOf` service for the active generation's official preset package and
|
|
23
|
+
The optional `cordisToolsEnabled` integration requires the current DSH installation to provide its shipped `cordis` preset plus the public preset, Skill, Cordis, settings, and tool-runtime services. PTC Plus declares the shared service packages as unrestricted required peers instead of installing private runtime copies. For a pathless preset it asks the Host's `pluginPackages.packageOf` service for the active generation's official preset package and selects `dsh-doc/SKILL.md`, falling back to the historical `cordis-plugin-development/SKILL.md`, before mounting the exact selected Skill; an older generation with no package service may resolve only its historical plural preset package relative to the Host's `ctx.baseUrl`. This compatibility path is disabled whenever `pluginPackages` exists, so packages merely reachable from the plugin profile cannot override an active Host result. Runtime capability validation owns compatibility, and CI checks the packed plugin against the blocking host channels resolved from `compat/channels.json`. Each result applies only to the tested cohort. That load step mounts the pathless Cordis companion from a separated active-host resource while a resolvable stale package is present beside the packed plugin, runs `scripts/dsh-execution-seam-smoke.mjs` to exercise public provider composition around the execution service the installed tool runtime uses, and runs `scripts/dsh-rpc-contract-smoke.mjs` to register the packed Remote descriptors with the installed TYPERT registry and evaluate the decoder that generation reads ([ADR 0030](adr/0030-serve-both-typert-codec-generations-from-one-codec.md)); an import alone cannot distinguish a loaded plugin from one whose injection is unsatisfied, because Cordis leaves the latter pending without an error, and it cannot show that the Host accepts a wire contract it validates only at registration. The same suite round-trips argument diagnostics through the selected Host's compressed JSONL Session persistence. Service packages retain the dependency graph selected by their Host distribution rather than independently selecting each service's release tag. DSH's profile module fallback must resolve the peers, while `pluginPackages` identifies the official preset resource from an active installation that publishes the service. Do not copy `SKILL.md` or add the Cordis preset's Skill directory to global roots. If the host surface is incomplete, plugin activation or enabling the setting fails instead of loading a second DSH core.
|
|
24
24
|
|
|
25
25
|
The plugin attaches to whichever program-execution service the installed DSH registers, and it presents the capabilities of the execution it performs ([ADR 0028](adr/0028-attach-to-the-host-ptc-execution-seam.md)). Cells run in the session kernel under the session's configured budgets, so `run_code` advertises neither a per-call deadline nor a file sandbox, and DSH rejects `timeoutMs` and `sandbox_permissions` with its own message instead of the plugin accepting an input it would then ignore.
|
|
26
26
|
|
|
@@ -32,7 +32,7 @@ The Client root requires `slots`, `locale`, `connection`, and `remote`; it adopt
|
|
|
32
32
|
|
|
33
33
|
### Compatibility Evidence
|
|
34
34
|
|
|
35
|
-
The plugin
|
|
35
|
+
The plugin declares a bounded `engines.dsh` range for manifest admission and leaves Host service peers unrestricted. This metadata does not prove a usable public extension surface; the selected Host must pass capability checks and packed contracts. Verification targets are expressed as channels, independently of the manifest range. `compat/channels.json` records, per channel, the host release each official dist-tag resolves to and the tarball integrity of every host package whose published surface the plugin probes. `latest` and `next` are the blocking channels; `alpha` carries the line this checkout develops against and reports without blocking a release. The development graph declares that channel rather than a release — every host `devDependencies` entry names it, and the lock resolves it — so a supported line is reached by moving the channel definition, not by editing the graph by hand. A probed package the release does not publish is recorded at the version and integrity its own declared dependency range resolves to, so a publish inside that range is a recorded drift; a probed package the release neither publishes nor depends on is recorded as absent, and the install proof rejects a graph that contains one. The recorded versions do not prove live registry availability or untested compatibility, and behaviour never branches on them: presentation, transport ownership and state retention are detected from the host's published shapes. `npm run host:channels:verify` checks the tracked manifest offline; `npm run host:channels:update` is the only command that resolves it from the registry.
|
|
36
36
|
|
|
37
37
|
| Retained interface | Evidence and consequence of removal |
|
|
38
38
|
| --- | --- |
|
|
@@ -54,7 +54,7 @@ Capabilities select behavior, never a release number. Historical fixture success
|
|
|
54
54
|
Use this form after the selected version is available from the npm registry:
|
|
55
55
|
|
|
56
56
|
```sh
|
|
57
|
-
dsh plugin --profile <profile> add dsh-ptc-plus@0.5.
|
|
57
|
+
dsh plugin --profile <profile> add dsh-ptc-plus@0.5.6
|
|
58
58
|
dsh --profile <profile> --dump-config
|
|
59
59
|
```
|
|
60
60
|
|
|
@@ -124,7 +124,7 @@ npm run readme:screenshots -- --dsh-entry /absolute/path/to/dsh/lib/bin.js
|
|
|
124
124
|
|
|
125
125
|
## Isolated latest-DSH development launcher
|
|
126
126
|
|
|
127
|
-
To test this checkout in a separate DSH installation, double-click `scripts\run-dev-dsh.cmd`. It orders all published DSH releases by semantic version, prereleases included, and selects the newest release whose complete dependency cohort npm can install, rather than following a dist-tag that a release can leave behind. If a newly published root package still has missing exact-version dependencies, the launcher warns and tries the preceding release; an explicit `DSH_DEV_VERSION` remains exact and fails instead of falling back. It installs only when the selected cached version changes, creates the shipped `web` profile inside an isolated `DSH_HOME`, installs this checkout, and starts DSH. When no port is supplied, the default Web profile reuses its cached loopback port while
|
|
127
|
+
To test this checkout in a separate DSH installation, double-click `scripts\run-dev-dsh.cmd`. It orders all published DSH releases by semantic version, prereleases included, and selects the newest release whose complete dependency cohort npm can install, rather than following a dist-tag that a release can leave behind. If a newly published root package still has missing exact-version dependencies, the launcher warns and tries the preceding release; an explicit `DSH_DEV_VERSION` remains exact and fails instead of falling back. It installs only when the selected cached version changes, creates the shipped `web` profile inside an isolated `DSH_HOME`, installs this checkout, and starts DSH. When no port is supplied, the default Web profile reuses its cached loopback port while the selected Windows Node runtime can listen on it; an invalid cache entry, occupied port, or Windows access denial replaces it with a free port. Newly allocated ports must pass an explicit Node listen after closing the allocation socket before they enter the cache. This keeps browser authentication stable across ordinary restarts without blocking another DSH on port 3080. Port probes release their sockets before DSH starts, so a later reservation or another process taking the port can still prevent startup; retry the launcher to recheck the cache. Explicit `DSH_DEV_PORT` and `--port` choices remain authoritative and are never silently replaced. The launched Host receives a 64 KiB HTTP request-header limit while retaining existing Node options to accommodate development authentication cookies and the combined Client plugin request during Web boot. The launcher does not modify tracked repository files, the checkout dependency directory, or your normal DSH home.
|
|
128
128
|
|
|
129
129
|
The launcher defaults to `https://registry.npmjs.org/` for version queries, npm installs and DSH's pnpm subprocesses, including the `@deepseek-ai` scope. This avoids mirror synchronization gaps where a new DSH package is available before its dependencies. It prints the selected registry and refreshes version metadata online; an unavailable version query can still reuse the previously cached version. Set `DSH_DEV_REGISTRY` to an absolute HTTP(S) registry URL to select another source explicitly. The choice applies only to the launcher process and its children; npm configuration files and persistent environment settings are unchanged. Other explicitly configured package scopes retain their own registries.
|
|
130
130
|
|
|
@@ -159,7 +159,7 @@ dsh plugin add github:muyuanjin/dsh-ptc-plus#main
|
|
|
159
159
|
dsh --dump-config
|
|
160
160
|
```
|
|
161
161
|
|
|
162
|
-
After an npm release, the package spec may instead be `dsh-ptc-plus@0.5.
|
|
162
|
+
After an npm release, the package spec may instead be `dsh-ptc-plus@0.5.6`. For a local package, use its absolute tarball path. Restart DSH Desktop after installation. Linux Desktop is not a current DSH Desktop release target; use DSH CLI/Web on Linux.
|
|
163
163
|
|
|
164
164
|
## Upgrades
|
|
165
165
|
|
package/docs/publishing.md
CHANGED
|
@@ -44,7 +44,7 @@ npm.cmd stage approve '<stage-id>' --registry=https://registry.npmjs.org/
|
|
|
44
44
|
|
|
45
45
|
1. 提交前在稳定工作树上运行完整 `npm run check`,执行无覆盖插桩的完整普通后端测试并生成 review proof。覆盖率只在准备发布新版本时运行;Release workflow 在打包与 npm staging 前对 release tag 执行 `npm run coverage`,要求行与函数覆盖率 100%、分支覆盖率至少 95%。发布准备期间可在本地运行同一命令,并用 `npm run coverage:focus` 诊断覆盖率缺口;日常开发、审查与提交不运行覆盖率专用套件、采集探针或插桩分支;这些测试由 `test/coverage/` 和发布入口的显式标记拥有。仓库 CI 在 Linux Node `22.19.0`、24.x、26.x,以及 Windows 与 macOS Node 24.x 的干净安装上运行 `npm run verify:ci`,检查构建、Client 与跨平台关键运行契约;Ubuntu Node 24.x 另运行打包后的 `latest` / `next` Host contracts。普通 CI 不收集 coverage 或执行穷尽式后端套件。
|
|
46
46
|
2. 运行 `npm audit --omit=dev`、`npx publint`、`git diff --check`、Markdown local-link check 和 `npm pack --silent --dry-run --json`。audit 检查随包安装的 production 依赖图;宿主 DSH 及其开发依赖不进入插件 tarball,由冻结宿主契约和 CI 单独验证。确认 tarball 只包含发布白名单内的运行时代码、文档和展示资产,不含凭据、本地路径、开发脚本或测试夹具,并执行 `npm run test:package:consumer -- <tarball>`:入口先校验当前安装的宿主与其 lock 一致,再将宿主实际提供的 peer 版本与 tarball 放在同一次 npm 安装事务中,在空目录执行 ESM import、内置编译器栈与内核 worker 加载 smoke。不能让 npm 对各宿主 peer 分别选用 dist-tag;插件继续声明不限制版本的 required peers,不私装宿主服务副本。机器读取 `npm pack --json` 时保持 `--silent`,避免 lifecycle 输出混入 JSON stream。
|
|
47
|
-
3. 更新到最新可用 DSH release 并记录 `dsh --version`。分别从 npm 包、固定 Git commit、源码 checkout 和 tarball 安装到临时 profile,再执行 `dsh --profile <profile> --dump-config`,确认与 `cordis.patch.yml` 一致:新增 `ptc-plus-execution`、`ptc-plus` 两项,并将原 `ptc-runtime` 的 `ptcRuntime` 服务隔离到 `ptc-plus-original`。每个上游 release 都重新验证公共扩展面、CLI/Web 集成和 profile
|
|
47
|
+
3. 更新到最新可用 DSH release 并记录 `dsh --version`。分别从 npm 包、固定 Git commit、源码 checkout 和 tarball 安装到临时 profile,再执行 `dsh --profile <profile> --dump-config`,确认与 `cordis.patch.yml` 一致:新增 `ptc-plus-execution`、`ptc-plus` 两项,并将原 `ptc-runtime` 的 `ptcRuntime` 服务隔离到 `ptc-plus-original`。每个上游 release 都重新验证公共扩展面、CLI/Web 集成和 profile 装配,并核对 `engines.dsh` 的上下界;范围内的宿主升级保留现有边界,运行时不按版本号选择接口。
|
|
48
48
|
4. 在 Windows 与 Linux 运行无模型调用的 `npm run test:client:web -- --dsh-entry <latest-installed-dsh/lib/bin.js>`,验证 tarball 安装后的真实 Web Client、设置与对话 surface;浏览器前置条件见 [安装指南](installation.md)。`build:check`、Host ESM import 和 factory smoke 均不能替代浏览器激活验收。macOS 由原生 runner 验证 CLI/Web;Windows 与 macOS Desktop 从托盘打开当前 profile 的 DSH Terminal 安装,重启 Desktop 后做一次 PTC 模式 smoke。Desktop 当前发布平台不包括 Linux。界面有变化时用同一前置条件刷新 README 截图:`npm run readme:screenshots -- --dsh-entry <latest-installed-dsh/lib/bin.js>` 从当前打包候选各写回一帧中英文 REPL 工作台与设置窗口;先用 `--out <directory>` 落到别处检查,命令、前置条件与失败边界见 [安装指南](installation.md)。
|
|
49
49
|
5. 只有在明确授权模型消耗后才运行 `npm run test:expensive` 与 `npm run test:ab`;发布候选还要用 `DSH_PTC_ACCEPTANCE_SCENARIOS=managed-adaptive-surface,managed-session-resume,managed-surface-change,subagent-continuity` 追加托管能力面、会话恢复、宿主表面变化与子代理场景(运行方式、预算与版本差异判别见[评估](evaluation.md#managed-session-continuity-cohort))。发布结论以结构化测试结果为准,不把一次模型样本推广为普遍保证。
|
|
50
50
|
6. 确认 npm 包名可用、待发布版本高于 registry 版本、README 截图来自真实 DSH 会话,并核对 repository、homepage、bugs、license 与 `dsh-plugin` topic。
|
package/docs/release-notes.md
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
4. **升级要求**:Node 版本、是否需要重启、是否有配置迁移。
|
|
26
26
|
5. **内部交付**默认不出现;只有当它改变用户可见结果时,才用用户能理解的方式提及。
|
|
27
27
|
|
|
28
|
-
兼容性声明落在公共扩展面上——设置座位、slot、公共 `Menu`
|
|
28
|
+
兼容性声明落在公共扩展面上——设置座位、slot、公共 `Menu` 区域、会话投影、能力探测。版本号可用于标明本次适配的目标发行及 `engines.dsh` 的安装准入范围;运行时能力与座位仍以宿主声明的公共扩展面为准([ADR 0017](adr/0017-track-the-latest-dsh-public-surface.md))。
|
|
29
29
|
|
|
30
30
|
## 风格
|
|
31
31
|
|