dsh-ptc-plus 0.5.6 → 0.5.8
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 +10 -2
- package/README.md +10 -2
- package/client.cjs +13 -23
- package/docs/adr/0020-optional-cordis-tools-in-ptc-mode.md +18 -12
- package/docs/adr/0038-freeze-session-capability-plans.md +1 -1
- package/docs/adr/0042-persist-provider-availability-and-handback.md +8 -4
- 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 +2 -2
- package/docs/capability-planning-components.md +1 -1
- package/docs/durability-design.md +10 -0
- package/docs/installation.md +2 -2
- package/docs/releases/v0.5.6.md +7 -3
- package/docs/releases/v0.5.7.md +51 -0
- package/docs/runtime-reference.md +4 -4
- package/internal/capability-environment.js +7 -3
- package/internal/config-spec.js +2 -2
- package/internal/cordis-tools-owner.js +32 -28
- package/internal/execution-seam-compat.js +13 -15
- package/internal/runtime-bridge-owner.js +7 -1
- package/internal/runtime-contexts.js +5 -1
- 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 +1 -1
- package/src/client-activity.js +4 -1
- package/src/client-settings-view.js +3 -10
package/README.en.md
CHANGED
|
@@ -39,6 +39,8 @@ Replace `<profile>` with your profile name, restart DSH, and select **PTC mode**
|
|
|
39
39
|
|
|
40
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
|
+
When DSH exits or restarts through its built-in updater, the plugin releases computation resources without scanning historical sessions. Unloading the plugin while DSH continues running still persists session handback notices; recovery after restart uses the session records.
|
|
43
|
+
|
|
42
44
|
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
45
|
|
|
44
46
|
## Feature overview
|
|
@@ -88,7 +90,7 @@ The default **stateful semantics** (`bindingUpdates: 'stateful'`) extend JavaScr
|
|
|
88
90
|
- 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
91
|
- A failed initialization does not permanently reserve that name, and changes made before the failure are not rolled back.
|
|
90
92
|
|
|
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.
|
|
93
|
+
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
94
|
|
|
93
95
|
`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
96
|
|
|
@@ -130,6 +132,8 @@ return capabilities.search({ query: 'read file content', budgetBytes: 8192 })
|
|
|
130
132
|
|
|
131
133
|
Search uses English/Chinese lexical matching, and a miss does not prove that a tool is unavailable. Discovery grants no additional authority, DSH still validates and schedules calls, and more usage notes are in [capability discovery](docs/runtime-reference.md#capability-discovery).
|
|
132
134
|
|
|
135
|
+
With capability management enabled, interface changes after a DSH update append a notice when the conversation resumes: on-demand capabilities share one retrieval instruction and a list of names, full disclosure supplies complete replacement contracts, and withdrawn capabilities explicitly revoke their earlier contracts. With the accepted notice retained and no further interface changes, continuation or restart does not repeat it.
|
|
136
|
+
|
|
133
137
|
## Global bindings: reuse functions across sessions
|
|
134
138
|
|
|
135
139
|
Session variables serve the current task, and **global bindings** save common TypeScript functions for multiple sessions to load: after saving `textTools`, the model can call `textTools.clean(text)`. Create entries by hand, import `.ts` files, or ask the model:
|
|
@@ -182,7 +186,9 @@ Stopping a background subagent preserves the parent session's REPL state, so cal
|
|
|
182
186
|
|
|
183
187
|
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
188
|
|
|
185
|
-
Session state is not permanent memory: after a restart
|
|
189
|
+
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.
|
|
190
|
+
|
|
191
|
+
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
192
|
|
|
187
193
|
## Boundaries
|
|
188
194
|
|
|
@@ -194,6 +200,8 @@ PTC Plus is a community plugin, with no affiliation with or endorsement from Dee
|
|
|
194
200
|
|
|
195
201
|
## Development
|
|
196
202
|
|
|
203
|
+
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).
|
|
204
|
+
|
|
197
205
|
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
206
|
|
|
199
207
|
```sh
|
package/README.md
CHANGED
|
@@ -39,6 +39,8 @@ dsh plugin --profile <profile> add dsh-ptc-plus
|
|
|
39
39
|
|
|
40
40
|
插件声明 DSH 兼容范围 `>=0.2.1-0 <0.2.3`,由宿主执行版本预检;范围内的接口适配仍通过公共能力检查与打包测试验证。
|
|
41
41
|
|
|
42
|
+
退出或通过内置更新重启 DSH 时,插件释放计算资源,不遍历历史会话。运行中单独卸载插件仍会持久化会话交接提示;重启后的状态恢复沿用会话记录。
|
|
43
|
+
|
|
42
44
|
界面默认显示会话里的 **REPL** 页签,宽屏顶部还有 **PTC Plus** 标志。输入框旁的星光按钮打开全局绑定菜单、会话能力工作台和 **PTC Plus 设置**,侧边栏的 **插件 → 已安装 → dsh-ptc-plus → 配置** 是同一套设置。
|
|
43
45
|
|
|
44
46
|
## 功能概览
|
|
@@ -88,7 +90,7 @@ return total() // 20
|
|
|
88
90
|
- 已有闭包读到更新后的绑定,提前保存的函数值仍是原来的函数;不同块、函数和循环迭代的作用域照常区分。
|
|
89
91
|
- 声明初始化失败不会永久占住这个名称,失败前已经生效的修改也不会回滚。
|
|
90
92
|
|
|
91
|
-
cell 支持 TypeScript(含运行时 `enum` 和 `namespace`)、顶层 `await` / `return` 和静态 `import` / `export`;静态导入在整个 cell
|
|
93
|
+
cell 支持 TypeScript(含运行时 `enum` 和 `namespace`)、顶层 `await` / `return` 和静态 `import` / `export`;静态导入在整个 cell 正文执行前生效,正文里的赋值随后可以覆盖它。设置中的“绑定更新语义”直接显示当前策略,可选择“允许重声明和覆盖”(`stateful`)或“启用名称保护”(`protected`);`tools` 这类受保护的运行时名称任何时候都不能覆盖。
|
|
92
94
|
|
|
93
95
|
`run_code`、编辑后的代码和全局绑定工作台采用同一套语言策略;显式 `eval`、`Function`、`node:vm` 或独立运行时仍受各自的原生边界约束。作用域、模块互操作和历史会话规则见[语言参考](docs/runtime-reference.md#cell-semantics),完整的语言规则、配置字段与诊断见[运行时参考](docs/runtime-reference.md)。
|
|
94
96
|
|
|
@@ -130,6 +132,8 @@ return capabilities.search({ query: 'read file content', budgetBytes: 8192 })
|
|
|
130
132
|
|
|
131
133
|
搜索按中英文词法匹配,没匹配到不代表工具不存在。发现工具不会增加权限,实际调用仍由 DSH 校验和调度,更多用法见[能力发现](docs/runtime-reference.md#capability-discovery)。
|
|
132
134
|
|
|
135
|
+
启用能力管理时,DSH 更新造成的接口变化会在续聊时追加通知:按需能力共用一条查询提示和名称列表,完整披露项提供完整新契约,已撤下项明确撤销旧说明;已接受的通知仍保留且接口未再变化时,继续会话或重启不会重复通知。
|
|
136
|
+
|
|
133
137
|
## 全局绑定:跨会话复用常用函数
|
|
134
138
|
|
|
135
139
|
会话变量服务于当前任务,**全局绑定**把常用 TypeScript 函数保存下来供多个会话加载:保存 `textTools` 之后,模型就能调用 `textTools.clean(text)`。你可以手动创建、导入 `.ts` 文件,也可以让模型帮忙:
|
|
@@ -180,7 +184,9 @@ return capabilities.search({ query: 'read file content', budgetBytes: 8192 })
|
|
|
180
184
|
|
|
181
185
|
在插件 graph IPC 支持的值范围内,程序参数、结果和恢复记录能保留 `undefined`、BigInt、`NaN`、无穷大、稀疏数组、循环引用和共享引用关系,支持的值直接返回即可,不必自己写 `JSON.stringify`(它会丢掉对象里的 `undefined`,把 `NaN` 和无穷大变成 `null`、把 `-0` 变成 `0`,还会拒绝 BigInt)。函数、Promise、类实例、Date、Map、Set 不在这个范围内,原生 `tools.*` 的 JSON 参数与结果契约也不受影响,详见[值契约](docs/value-wire.md)。
|
|
182
186
|
|
|
183
|
-
|
|
187
|
+
会话状态不是永久内存:重启或上下文压缩后,只保留能从会话记录验证、且来源仍在模型上下文中的状态,其余会被丢弃并给出提示,必要时从空环境继续当前计算。会话记录本身缺失或损坏时会明确报错,不会被当作成功恢复的空会话。恢复不会重新派发已记录的原生工具调用,也不会撤销历史外部效果,依据和限制见[运行时参考](docs/runtime-reference.md)。
|
|
188
|
+
|
|
189
|
+
宿主显式重置程序环境时,会清除会话变量、命名 checkpoint 和可编辑目标;重启或 fork 后也不会恢复重置前的状态。已完成的外部操作保留,全局绑定配置保持有效。
|
|
184
190
|
|
|
185
191
|
停止后台子代理不会清空父会话的 REPL 状态;通知触发的后续调用可以继续使用父会话的变量。父会话自身释放后,后续调用仍按上述恢复规则继续计算。
|
|
186
192
|
|
|
@@ -194,6 +200,8 @@ PTC Plus 是社区插件,与 DeepSeek 或 DSH 无隶属或背书关系。
|
|
|
194
200
|
|
|
195
201
|
## 开发
|
|
196
202
|
|
|
203
|
+
Windows 可双击 `scripts\run-dev-dsh.cmd` 启动隔离开发环境;默认复用经 Windows Node.js 实测可监听的端口,缓存端口被占用或拒绝访问时自动更换。手动指定的端口保持原值,详见[安装指南](docs/installation.md)。
|
|
204
|
+
|
|
197
205
|
开发在仓库根目录进行:`npm ci` 安装依赖,`npm run build` 重新生成 `client.cjs` 和 compiler 产物。聚焦测试必须指定用例:
|
|
198
206
|
|
|
199
207
|
```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;
|
|
@@ -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
|
|
|
@@ -24,7 +24,7 @@ Automatic allocation uses session-family coverage rather than raw call volume. A
|
|
|
24
24
|
|
|
25
25
|
Allocation considers both coverage and contract length within a configurable explanation budget. The directory has its own bound; every long-tail name need not remain in the prompt. Explicit full disclosure overrides the explanation budget, with an observable overage rather than silent truncation or demotion. A budget overage does not establish that a request fits a model's physical context limit.
|
|
26
26
|
|
|
27
|
-
A session capability plan records the effective enablement and disclosure choices when the session begins. Statistics and saved configuration do not redistribute an existing session, including after restoration. A user-triggered slash command explicitly refreshes the session. Refresh synchronizes descriptions, discovery and runtime exposure and supplies a durable, model-visible notification consistent with what actually became effective. A UI receipt alone is insufficient. Refresh uses Host lifecycle boundaries and does not require a paid model request merely to execute the human command. A stored plan cannot preserve a capability that its Host owner has actually removed or forbidden. Symmetrically, a live Host member that the frozen plan has not yet allocated remains declared under the Host's own presentation — or under its explicit availability closure — until refresh folds it into the plan; a pending allocation boundary never removes the member's identity from the declaration, discovery or dispatch surfaces. The frozen choice does not freeze the calling contract. Live parameter, output, instruction-dependency and Skill invocation changes append a validated `ptc-capability-contracts/
|
|
27
|
+
A session capability plan records the effective enablement and disclosure choices when the session begins. Statistics and saved configuration do not redistribute an existing session, including after restoration. A user-triggered slash command explicitly refreshes the session. Refresh synchronizes descriptions, discovery and runtime exposure and supplies a durable, model-visible notification consistent with what actually became effective. A UI receipt alone is insufficient. Refresh uses Host lifecycle boundaries and does not require a paid model request merely to execute the human command. A stored plan cannot preserve a capability that its Host owner has actually removed or forbidden. Symmetrically, a live Host member that the frozen plan has not yet allocated remains declared under the Host's own presentation — or under its explicit availability closure — until refresh folds it into the plan; a pending allocation boundary never removes the member's identity from the declaration, discovery or dispatch surfaces. The frozen choice does not freeze the calling contract. Live parameter, output, instruction-dependency and Skill invocation changes append a validated `ptc-capability-contracts/v2` notification at an accepted step, retaining the original plan digest and current revision vector. Full choices receive complete replacement contracts; on-demand choices receive a revision notice and current discovery; removed capabilities receive a withdrawal. Saved settings and statistics still cannot reallocate that session. Unchanged views do not repeat notifications, and recovery uses visible validated notifications without rewriting the initial plan or prefix. The v2 body groups all changed on-demand identities under one instruction to retrieve each current complete contract before invocation. Full contracts, deduplicated owner dependencies and individual withdrawals retain their complete statements. Historical v1 notifications retain their exact original per-capability body; validation dispatches by the recorded generation, rejects unknown generations and modified bodies, and accepts retained v1 evidence for deduplication after an upgrade. The source snapshot and revision evidence remain in the session record; grouping changes the model-visible body, not the capability choices or calling interfaces.
|
|
28
28
|
|
|
29
29
|
Explicit session choices and saved choices have separate owners. `/capabilities set session <encoded-id> <full|on-demand|closed|automatic|inherit>` changes only the current session. `automatic` explicitly removes that identity's saved manual override from the effective input; `inherit` removes its temporary override and resumes the adopted source choice. Ordinary `/capabilities refresh` adopts current saved configuration while retaining temporary choices. `/capabilities set global <encoded-id> <full|on-demand|closed|automatic>` saves through the public revision-checked settings writer and updates this session in the same Host maintenance operation, clearing only that identity's temporary choice. Other existing sessions remain frozen. Server choices allow only `closed`, `automatic` and session `inherit`; their closure precedes child choices, and reopening preserves children.
|
|
30
30
|
|
|
@@ -14,11 +14,13 @@ Provider availability is a source-owned append-only fact, distinct from computat
|
|
|
14
14
|
|
|
15
15
|
The passive runtime-message owner publishes disablement or resumed availability only through a witnessed, accepted, non-aborted Host step. Rejected, paused or cancelled proposals do not become delivery. Existing plugin declarations or a plugin journal namespace establish prior provider participation; journal presence does not prove any binding recoverable, initialized, live or known to the model. Repetition does not append a duplicate withdrawal. Re-enablement cannot restore a capability plan preceding the last validated withdrawal.
|
|
16
16
|
|
|
17
|
-
Complete plugin release first awaits the existing runtime controller's worker and registration cleanup, then persists unloaded availability while public session services remain available. Loaded sessions use their real Session append and Host flush. Unloaded stored sessions use the public persistence list and exclusive write handle, validate their surface with public pure interpreters, and append their own new withdrawal fact with append/flush/close. No Agent is created, model awakened, effect replayed, event sequence fabricated or second session coordinator introduced.
|
|
17
|
+
Complete plugin release first awaits the existing runtime controller's worker and registration cleanup. When the application remains running, it then persists unloaded availability while public session services remain available. Loaded sessions use their real Session append and Host flush. Unloaded stored sessions use the public persistence list and exclusive write handle, validate their surface with public pure interpreters, and append their own new withdrawal fact with append/flush/close. No Agent is created, model awakened, effect replayed, event sequence fabricated or second session coordinator introduced.
|
|
18
|
+
|
|
19
|
+
Whole application shutdown has no continuing model request to hand back to a native provider. When the public Cordis root fiber is unloading, release completes runtime cleanup without enumerating loaded or stored sessions or appending withdrawals. The plugin's own unloading state does not establish application shutdown: a provider-only unload still performs durable handback. Restarted providers reconcile availability at their next accepted Host step and recover computation only from independently verified session evidence. Process shutdown does not preserve a live heap or establish recovery proof.
|
|
18
20
|
|
|
19
21
|
The lifecycle owner captures the public session, query and persistence services while they exist, rather than looking them up after removal. Loaded history uses a public immutable query cut. Offline handback is a new fact written by the releasing provider, not a Session resume: the exclusive public write handle supplies validated stored events and their next offset; `foldSurface` and `deriveEventMessage` apply installed first-party and live registered pure interpreters; `snapshotSessionEvent` validates the producer's own new `user/message` envelope; the extended surface is validated before `handle.append`, `flush` and `close`. It does not instantiate or publish an offline Session, invent a foreign resume marker, impersonate a user or command, or use deprecated synchronous readers. A loaded session whose query dependencies are already destroyed still reports that failure; retaining a service object does not recreate its dependencies.
|
|
20
22
|
|
|
21
|
-
Each session is independent. A writer conflict, damaged storage, flush refusal or unavailable public persistence ownership remains a real handback failure; cleanup continues for other sessions and aggregates these failures. The plugin never steals another process's writer. Successful in-memory append alone is not crash-durable evidence.
|
|
23
|
+
Each session is independent. A writer conflict, damaged storage, flush refusal or unavailable public persistence ownership remains a real provider-only handback failure; cleanup continues for other sessions and aggregates these failures. The plugin never steals another process's writer. Successful in-memory append alone is not crash-durable evidence. Dependency removal or external ownership can prevent persistence, so complete handback cannot be claimed in those cases. The failure must remain observable to the Host lifecycle owner; no promise is made that a destroyed dependency can still write. Runtime cleanup failures remain observable during both provider-only release and application shutdown.
|
|
22
24
|
|
|
23
25
|
User binding toggles publish a separate configuration receipt only after storage confirms the revision and entry. A public Conversation definition renders the source-validated receipt as its own visible node using current Client locale. The receipt proves saved enablement only; model catalog delivery still follows accepted-step publication and worker initialization still follows actual execution. It has no turn-trigger identity and does not wake a task. Capability command receipts similarly distinguish updated, pending first acceptance, unavailable, invalid usage, and globally saved but not applied states.
|
|
24
26
|
|
|
@@ -30,12 +32,14 @@ User binding toggles publish a separate configuration receipt only after storage
|
|
|
30
32
|
|
|
31
33
|
**Steal offline ownership or edit JSONL files.** It bypasses the Host's single-writer and validation contracts. Refusal is preserved and reported, not converted to successful handback.
|
|
32
34
|
|
|
35
|
+
**Persist archive-wide withdrawals during application shutdown.** No native request continues in that process, and historical storage size would determine whether the Host can acknowledge shutdown to its updater. Shutdown owns resource release; provider-only removal owns durable handback to a continuing Host.
|
|
36
|
+
|
|
33
37
|
**Use user/command/turn-trigger events for a binding toggle.** It confuses saved configuration with task initiation and may wake a model. A separately sourced fact and public renderer preserve both lifecycle and visibility.
|
|
34
38
|
|
|
35
39
|
## Consequences
|
|
36
40
|
|
|
37
|
-
Availability is reconstructable in native sessions after plugin removal without a plugin-specific projection interpreter. A declaration withdrawal cannot preserve the old continuous heap, prove source knowledge, provide missing Host tools or solve the independent top-level editor admission boundary. Persistence failures are explicit partial lifecycle outcomes.
|
|
41
|
+
Availability is reconstructable in native sessions after provider-only plugin removal without a plugin-specific projection interpreter. Whole application shutdown does not traverse the session archive and still awaits resource release. A declaration withdrawal cannot preserve the old continuous heap, prove source knowledge, provide missing Host tools or solve the independent top-level editor admission boundary. Persistence failures are explicit partial lifecycle outcomes.
|
|
38
42
|
|
|
39
43
|
## Evidence
|
|
40
44
|
|
|
41
|
-
`test/runtime-messages.test.js`, `test/capability-environment.test.js`, `test/user-bindings-owner.test.js` and `test/client-runtime.spec.js` exercise accepted publication, restoration, storage confirmation and locale rendering.
|
|
45
|
+
`test/runtime-messages.test.js`, `test/capability-environment.test.js`, `test/user-bindings-owner.test.js` and `test/client-runtime.spec.js` exercise accepted publication, restoration, storage confirmation and locale rendering. `test/execution-provider-owner.test.js` exercises whole-root Loader shutdown before any conversation and after a journaled computation, including actual worker exit and refusal of archive access. Current packed-Host integration evidence remains necessary for installed desktop update claims; fixtures do not stand in for that boundary.
|
|
@@ -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
|
@@ -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
|
|
|
@@ -66,7 +66,7 @@ capabilityCoverage(state, { userId, workspaceId, id, revision })
|
|
|
66
66
|
|
|
67
67
|
宿主 prompt section 的空字符串或纯空白说明不形成契约依赖,但其 section 身份仍可证明 MCP server 归属。工具签名和资源契约保持可发现;非空说明原样保留并去重,非字符串等无效依赖仍由方案校验拒绝。
|
|
68
68
|
|
|
69
|
-
工具完整契约与程序检索元数据来自公共 `ToolRuntime.schemas(scope)` 与 `ToolRuntime.get(name, scope).output.schema` 的准确 JSON 快照,包含参数及返回值 schema;输出 schema 也参与修订身份和恢复比较。新 cell 的检索与 inspect 从同一份当前 SDK 快照派生结构化 schema、签名、依赖及修订,不将冻结方案中的旧签名覆盖到新返回值类型上;冻结的是启用与披露选择。每次准备与接受步骤重新读取 live owner 契约;同名工具的参数、输出或说明依赖变化,以及 Skill 调用资格变化或能力移除,以 `capability-contracts` 的 `ptc-capability-contracts/
|
|
69
|
+
工具完整契约与程序检索元数据来自公共 `ToolRuntime.schemas(scope)` 与 `ToolRuntime.get(name, scope).output.schema` 的准确 JSON 快照,包含参数及返回值 schema;输出 schema 也参与修订身份和恢复比较。新 cell 的检索与 inspect 从同一份当前 SDK 快照派生结构化 schema、签名、依赖及修订,不将冻结方案中的旧签名覆盖到新返回值类型上;冻结的是启用与披露选择。每次准备与接受步骤重新读取 live owner 契约;同名工具的参数、输出或说明依赖变化,以及 Skill 调用资格变化或能力移除,以 `capability-contracts` 的 `ptc-capability-contracts/v2` 来源消息更新当前效力。消息记录原方案 digest、当前修订向量、变化项和当前完整说明超额,digest 与精确正文共同校验;不修改原方案。仍选完整的项提供完整新契约和去重依赖,按需项合并为一条调用前检索当前完整契约的提示及变化身份列表,移除项逐项明确撤销。历史 v1 消息保留原有逐项正文,新 v2 按分组正文核验;两代均校验 digest 与精确正文,保留的有效旧通知仍参与恢复去重,未知代际不作为证据。投递经 accepted step,拒绝与取消不提交;未变视图不重复追加,恢复按正式可见消息协调。实际可用和使用统计采用当时的契约修订,已准入调用保留捕获时的观察身份。顶层模型工具 schema、准入与调用规范化继续使用独立的 `ToolRuntime.schemas(scope)`,不向模型工具定义追加 SDK 输出字段。冻结方案只为冻结时已捕获的身份保存选择;宿主随后 live 提供且未被显式关闭的新成员保持宿主声明(工具保留 SDK 命名成员与类型化签名,Skill 保持可加载),刷新才把它折入方案,刷新边界不把成员身份从声明、检索或分派面移除。
|
|
70
70
|
|
|
71
71
|
Skill 目录的 `snapshot.complete` 由公共 registry 拥有,表示本次 provider 发现与 revision 稳定性已证明。暂时不完整不证明某个 Skill 已撤下:已有冻结环境保留最近完整观察或已校验、已接受的本会话 `capability-contracts` 更新所证明的 Skill 视图,不发布未完整证明的新 Skill,也不把这轮 Skill 观察计为新的统计资格。工具与 MCP 继续消费当前 live owner。冷恢复沿同一已接受契约来源保留确证撤下结果,不能由初始快照复活旧 Skill。新环境和显式刷新仍要求完整目录,失败保留旧环境;取消和真实 Host 错误保持原语义。session Skill projection 仅在实际输出变化时调用 registration-scoped `invalidate()`,不因每次父子会话准备使全局 revision 无意义变化。
|
|
72
72
|
|
|
@@ -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
|
@@ -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
|
|
|
@@ -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
|
|
package/docs/releases/v0.5.6.md
CHANGED
|
@@ -2,16 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
<h3 id="cn-v056">宿主适配</h3>
|
|
4
4
|
|
|
5
|
+
* 适配 DSH `0.2.2-rc.1` 的公共工具执行接口,保留上一代宿主的调用方式;运行时接口按宿主提供的公共能力选择
|
|
5
6
|
* 声明 DSH 兼容范围 `>=0.2.1-0 <0.2.3`,由宿主按官方版本预检规则判断安装与启动资格;`0.2.2-rc.1` 在该范围内
|
|
6
7
|
|
|
7
8
|
<h3>修复</h3>
|
|
8
9
|
|
|
10
|
+
* 新版 DSH 中,`edit_run_code` 接受的修订保留原调用关系和本次运行可用的工具范围,继续遵循宿主策略与取消决定;后续单元格能继续使用修订后的状态
|
|
9
11
|
* 修复 0.5.5 将 DSH 兼容范围意外改成 `*` 的问题,恢复 0.5.4 的上下界;范围内的运行时接口仍按宿主公共能力选择
|
|
10
12
|
|
|
11
13
|
<h3>升级</h3>
|
|
12
14
|
|
|
13
15
|
* Node.js 需同时满足插件的 `^22.19.0 || >=24.0.0` 与所选 DSH 的要求;DSH `0.2.2-rc.1` 要求 Node.js `>=24.9.0`
|
|
14
|
-
* 无需迁移插件配置;升级后重启 DSH
|
|
16
|
+
* 无需迁移插件配置;升级后重启 DSH。插件升级不会自动改写历史会话日志
|
|
15
17
|
|
|
16
18
|
```sh
|
|
17
19
|
dsh plugin --profile <profile> add dsh-ptc-plus@0.5.6
|
|
@@ -21,16 +23,18 @@ dsh plugin --profile <profile> add dsh-ptc-plus@0.5.6
|
|
|
21
23
|
|
|
22
24
|
<h3 id="en-v056">Host Compatibility</h3>
|
|
23
25
|
|
|
26
|
+
* Adapts to the public tool execution interface of DSH `0.2.2-rc.1` while retaining the previous Host invocation contract; runtime interfaces follow the Host's public capabilities
|
|
24
27
|
* Declares the DSH compatibility range `>=0.2.1-0 <0.2.3`; the Host applies its official version preflight to installation and startup. This range includes `0.2.2-rc.1`
|
|
25
28
|
|
|
26
29
|
<h3>Fixes</h3>
|
|
27
30
|
|
|
31
|
+
* On the new DSH, a revision accepted by `edit_run_code` retains its original call relationship and the tools admitted for that run, and continues to follow Host policy and cancellation; later cells can continue using the revised state
|
|
28
32
|
* Fixes 0.5.5 unintentionally changing the DSH compatibility range to `*`, restoring the bounds from 0.5.4; runtime interfaces within that range continue to follow the Host's public capabilities
|
|
29
33
|
|
|
30
34
|
<h3>Upgrade</h3>
|
|
31
35
|
|
|
32
36
|
* Node.js must satisfy both the plugin's `^22.19.0 || >=24.0.0` range and the selected DSH requirements; DSH `0.2.2-rc.1` requires Node.js `>=24.9.0`
|
|
33
|
-
* No plugin configuration migration is needed; restart DSH after upgrading
|
|
37
|
+
* No plugin configuration migration is needed; restart DSH after upgrading. A plugin upgrade does not rewrite historical session logs automatically
|
|
34
38
|
|
|
35
39
|
```sh
|
|
36
40
|
dsh plugin --profile <profile> add dsh-ptc-plus@0.5.6
|
|
@@ -38,4 +42,4 @@ dsh plugin --profile <profile> add dsh-ptc-plus@0.5.6
|
|
|
38
42
|
|
|
39
43
|
---
|
|
40
44
|
|
|
41
|
-
Full Changelog: https://github.com/muyuanjin/dsh-ptc-plus/compare/v0.5.
|
|
45
|
+
Full Changelog: https://github.com/muyuanjin/dsh-ptc-plus/compare/v0.5.4...v0.5.6
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
[中文](#cn-v057) | [English](#en-v057)
|
|
2
|
+
|
|
3
|
+
<h3 id="cn-v057">宿主适配</h3>
|
|
4
|
+
|
|
5
|
+
* 适配 DSH `0.2.2-rc.2` 的官方 Cordis 开发 Skill;启用 `cordisToolsEnabled` 后加载 `dsh-doc`,同时保留旧版宿主的兼容入口
|
|
6
|
+
* DSH 安装准入范围保持 `>=0.2.1-0 <0.2.3`;运行时接口继续按宿主提供的公共能力选择
|
|
7
|
+
|
|
8
|
+
<h3>修复</h3>
|
|
9
|
+
|
|
10
|
+
* 宿主显式重置程序环境后,会话变量、命名 checkpoint 和可编辑目标会被清除,重启或 fork 后也不会恢复;普通 Agent 释放仍保留可验证的会话恢复
|
|
11
|
+
* 历史重置记录缺失或包含不支持的版本时,只收缩一次无法验证的状态;后续已确认的新计算可跨冷恢复和 fork 保留,不重复执行历史外部操作
|
|
12
|
+
* 包含多次重置的会话日志可正常迁移,并保留重置后计算的恢复关系
|
|
13
|
+
* Windows 开发启动器使用实际 Windows Node.js 检查监听端口,自动替换被占用或拒绝访问的缓存端口;手动指定的端口保持原值,探测失败时保留原缓存并停止启动
|
|
14
|
+
* “绑定更新语义”设置直接显示当前策略,可选择“允许重声明和覆盖”(`stateful`)或“启用名称保护”(`protected`);已有配置值保持不变
|
|
15
|
+
|
|
16
|
+
<h3>升级</h3>
|
|
17
|
+
|
|
18
|
+
* Node.js 需同时满足插件的 `^22.19.0 || >=24.0.0` 与所选 DSH 的要求;DSH `0.2.2-rc.2` 要求 Node.js `>=24.9.0`
|
|
19
|
+
* 无需迁移插件配置;升级后重启 DSH。插件升级不会自动改写历史会话日志
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
dsh plugin --profile <profile> add dsh-ptc-plus@0.5.7
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
<h3 id="en-v057">Host Compatibility</h3>
|
|
28
|
+
|
|
29
|
+
* Adapts to the official Cordis development Skill in DSH `0.2.2-rc.2`: enabling `cordisToolsEnabled` loads `dsh-doc`, while retaining the compatibility entry for older Hosts
|
|
30
|
+
* The DSH admission range remains `>=0.2.1-0 <0.2.3`; runtime interfaces continue to follow the Host's public capabilities
|
|
31
|
+
|
|
32
|
+
<h3>Fixes</h3>
|
|
33
|
+
|
|
34
|
+
* An explicit Host environment reset clears session variables, named checkpoints and edit targets across restart and fork; ordinary Agent disposal still preserves verifiable session recovery
|
|
35
|
+
* Missing or unsupported versions in historical reset records contract unproved state once; subsequently confirmed computation survives cold recovery and fork without repeating historical external operations
|
|
36
|
+
* Session logs containing multiple resets migrate successfully while preserving recovery relationships for post-reset computation
|
|
37
|
+
* The Windows development launcher probes listening ports with the actual Windows Node.js runtime and replaces occupied or denied cached ports; explicit ports remain unchanged, and failed probes preserve the cache and stop startup
|
|
38
|
+
* The “Binding update semantics” setting displays the selected policy by name: “Allow redeclarations and overrides” (`stateful`) or “Protect names” (`protected`); existing configuration values remain unchanged
|
|
39
|
+
|
|
40
|
+
<h3>Upgrade</h3>
|
|
41
|
+
|
|
42
|
+
* Node.js must satisfy both the plugin's `^22.19.0 || >=24.0.0` range and the selected DSH requirements; DSH `0.2.2-rc.2` requires Node.js `>=24.9.0`
|
|
43
|
+
* No plugin configuration migration is needed; restart DSH after upgrading. A plugin upgrade does not rewrite historical session logs automatically
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
dsh plugin --profile <profile> add dsh-ptc-plus@0.5.7
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
Full Changelog: https://github.com/muyuanjin/dsh-ptc-plus/compare/v0.5.6...v0.5.7
|