dsh-ptc-plus 0.5.6 → 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 CHANGED
@@ -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. To detect name overwrites instead, disable **Allow redeclarations and overrides** and use the `protected` policy; protected runtime names such as `tools` can never be overwritten.
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, a runtime reset, 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.
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
@@ -88,7 +88,7 @@ return total() // 20
88
88
  - 已有闭包读到更新后的绑定,提前保存的函数值仍是原来的函数;不同块、函数和循环迭代的作用域照常区分。
89
89
  - 声明初始化失败不会永久占住这个名称,失败前已经生效的修改也不会回滚。
90
90
 
91
- cell 支持 TypeScript(含运行时 `enum` 和 `namespace`)、顶层 `await` / `return` 和静态 `import` / `export`;静态导入在整个 cell 正文执行前生效,正文里的赋值随后可以覆盖它。想检测名称覆盖,可以在设置里关掉“允许重声明和覆盖”改用 `protected` 策略;`tools` 这类受保护的运行时名称任何时候都不能覆盖。
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
- 会话状态不是永久内存:重启、执行环境重置或上下文压缩后,只保留能从会话记录验证、且来源仍在模型上下文中的状态,其余会被丢弃并给出提示,必要时从空环境继续当前计算。会话记录本身缺失或损坏时会明确报错,不会被当作成功恢复的空会话。恢复不会重新派发已记录的原生工具调用,也不会撤销历史外部效果,依据和限制见[运行时参考](docs/runtime-reference.md)。
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: "\u8DE8 cell \u58F0\u660E\u7B56\u7565",
1969
- labelEn: "Cross-cell declaration policy",
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
- migratingPolicy ? h(Select2, {
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 the `cordis-plugin-development` companion Skill 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.
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 `cordis-plugin-development`; 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)).
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 `cordis-plugin-development` 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)).
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 accepts a root only when it contains the exact `cordis-plugin-development/SKILL.md`; it does not infer support from a package name or directory alone. 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.
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 Considered
29
+ ## Alternatives considered
30
30
 
31
- 1. Add the Cordis row to the PTC preset. Rejected: 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
- 2. Register Cordis tools during `system-prompt/assemble` and continue with the existing assembly. Rejected: 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.
33
- 3. Copy the tool definitions or their current names. Rejected: 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.
34
- 4. Enable the tools by default. Rejected: 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.
35
- 5. Mount one global Cordis tool fiber and hide it from native agents. Rejected: 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.
36
- 6. Copy `SKILL.md` into PTC Plus or add the Cordis preset's directory to global Skill roots. Rejected: copied instructions drift, while a global root leaks the optional workflow into agents that did not enable it.
37
- 7. Publish the complete preset-local Skill directory. Rejected: 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.
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.
@@ -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.
@@ -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 与 `cordis-plugin-development` 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。
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。只有准确存在 `cordis-plugin-development/SKILL.md` 才进入 mount;已发布但无效的 path 不回退到另一 generation 的 package layout。
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:
@@ -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 requires the exact `cordis-plugin-development/SKILL.md` before mounting it; 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.
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 that port is available; an invalid cache entry or occupied port is replaced with a free port. This keeps browser authentication stable across ordinary restarts without blocking another DSH on port 3080. 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.
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
 
@@ -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.5...v0.5.6
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
@@ -148,17 +148,17 @@ Missing-description diagnostics append a complete DSH user message to `additiona
148
148
  tipEscalationFailures: 2
149
149
  ```
150
150
 
151
- The five legacy binding and module switches remain migration inputs. Complete enabled/protected choices map to the corresponding new policy; mixed old choices retain their effective controls until the user explicitly selects the new switch. The Host schema preserves an omitted `bindingUpdates` value until migration, and the settings card resolves the same policy. Selecting the switch also clears the compatibility marker.
151
+ The five legacy binding and module switches remain migration inputs. Complete enabled/protected choices map to the corresponding new policy; mixed old choices retain their effective controls until the user explicitly selects a policy. The Host schema preserves an omitted `bindingUpdates` value until migration, and the settings card resolves the same policy. The **Binding update semantics** selector displays **Legacy settings (not migrated)** until a policy is selected, then shows **Allow redeclarations and overrides** (`stateful`) or **Protect names** (`protected`). Selecting a policy also clears the compatibility marker.
152
152
 
153
153
  `enabled: false` is the settings-based kill switch: the Host keeps the settings namespace, client card, and passive cleanup that can withdraw old PTC declarations at the next permitted accepted step. It removes execution hooks, prompt sections, and tool surfaces without reading binding storage. Settings are applied live when their owner can reconcile them, except the capability inputs frozen per session above and the activation-only seam wait `executionSeamTimeoutMs`, which is read when the plugin activates or reloads. A submitted cell retains one configuration snapshot for its budgets and policies through preflight, execution, binding calls, completion validation, and diagnostics; an update accepted while it runs applies to cells submitted afterward. Worker lifecycle bounds are not cell budgets: `maxOldGenerationSizeMb` is fixed at creation, and `workerReclaimMs` and `startupProbeMs` are read from the current configuration when a worker is created or closed. Node fixes a worker's V8 old-generation limit at creation, so changing `maxOldGenerationSizeMb` while a session worker is active or a submitted cell is preparing to execute is rejected and rolled back rather than reported as applied. Other non-`enabled` updates reconfigure existing owners without replacing session-bound bindings. The settings card renders in whichever settings seat the installed DSH declares — the sidebar **Plugins → Installed** page per-bundle configuration (`plugins.row.config`), or the preceding Host's **Settings → Plugin configuration** card (`settings.plugin.item`) ([ADR 0019](adr/0019-plugin-settings-and-kill-switch.md)) — places the main switch beside the PTC Plus title and disables every other control while the plugin is off. The card does not register in General settings; the sparkle menu opens the same complete form in an application dialog. If a live enable or reconfiguration cannot install a complete runtime, PTC Plus unwinds or restores every owner and persists the last applied settings; a failed compensating settings write is surfaced as an activation diagnostic. The TypeScript language check is deferred until runtime activation, so a non-TypeScript host can load the plugin in disabled mode but cannot enable it.
154
154
 
155
155
  `startupProbeMs` bounds the worker startup conformance probe, which must settle before the kernel reports ready. The worker reads the value from its startup data and falls back to 5000 ms when it is absent; a healthy probe settles inside the worker's own microtasks, so the bound can only fire when startup itself yields or blocks, and the failure is reported as a startup diagnostic without executing any cell. That worker-side read is verified by inspection rather than by a timer test, because a healthy probe never reaches the bound.
156
156
 
157
- `officialReplPriority` defaults to `false` and is evaluated against the live provider capability rather than a release number: a provider that declares `retainsState: true` keeps a program environment per state owner, and a provider that predates that declaration answers through the one retained source form (`programFormat: 'repl'`). With the setting enabled and such a provider live, this host attachment installs no session runtime, so `run_code` and its descriptors — `programFormat`, `retainsState`, `executionInstructions`, `sandboxMode` and `timeout` — stay with the official provider, and the plugin's REPL guidance, session-state semantics, recovery, editor tool, capability SDK, REPL observation and binding workbench are suspended until ownership changes back. The settings card, enablement and stored global bindings remain available so the switch can be reversed. Changing the setting or the host mode re-evaluates ownership as an installation change: the retired attachment disposes its live kernels before the other shape installs, so no committed cell mixes owners. Calls executed under the official mode produce no plugin journal records and are never recovery evidence. The plugin's provider surface forwards `programFormat` to the live original, answers `retainsState` for itself (an installed session kernel retains a per-session environment; otherwise the original declaration decides) and retains weak owner-to-original dispatch provenance for `release(owner)` — captured Agent cleanup reaches the original instances that served that owner even after adapter removal or source replacement, and a failed cleanup remains available for explicit retry. Owner-keyed retained environments and the executed program format belong to the provider that actually runs the program, and non-session consumers such as the workflow adapter keep executing through it — while `executionInstructions`, `sandboxMode` and `timeout` stay withheld while PTC Plus owns session execution. The plugin's own session kernel state is keyed by session and released through the plugin lifecycle, not by `release(owner)`.
157
+ `officialReplPriority` defaults to `false` and is evaluated against the live provider capability rather than a release number: a provider that declares `retainsState: true` keeps a program environment per state owner, and a provider that predates that declaration answers through the one retained source form (`programFormat: 'repl'`). With the setting enabled and such a provider live, this host attachment installs no session runtime, so `run_code` and its descriptors — `programFormat`, `retainsState`, `executionInstructions`, `sandboxMode` and `timeout` — stay with the official provider, and the plugin's REPL guidance, session-state semantics, recovery, editor tool, capability SDK, REPL observation and binding workbench are suspended until ownership changes back. The settings card, enablement and stored global bindings remain available so the switch can be reversed. Changing the setting or the host mode re-evaluates ownership as an installation change: the retired attachment disposes its live kernels before the other shape installs, so no committed cell mixes owners. Calls executed under the official mode produce no plugin journal records and are never recovery evidence. The plugin's provider surface forwards `programFormat` to the live original, answers `retainsState` for itself (an installed session kernel retains a per-session environment; otherwise the original declaration decides) and retains weak owner-to-original dispatch provenance for `release(owner)` — captured Agent cleanup reaches the original instances that served that owner even after adapter removal or source replacement, and a failed cleanup remains available for explicit retry. Owner-keyed retained environments and the executed program format belong to the provider that actually runs the program, and non-session consumers such as the workflow adapter keep executing through it — while `executionInstructions`, `sandboxMode` and `timeout` stay withheld while PTC Plus owns session execution. The plugin's own kernel is keyed by session. For a live session Agent, `release(owner)` implements the Host's explicit reset: it releases the kernel and appends a durable reset boundary, clearing earlier bindings, named checkpoints and edit targets from subsequent computation. For an Agent scope whose public Cordis fiber uid is already null, release is lifecycle cleanup and preserves proven cold recovery. Both routes also clean up original-provider state; failures propagate for Host-managed retry. Non-session owners retain original-provider delegation.
158
158
 
159
- `cordisToolsEnabled: true` atomically mounts the official `@deepseek-ai/dsh-tool-cordis` plugin and exactly the shipped `cordis-plugin-development` companion Skill in agent scopes that expose the `run_code` and `skill` tools plus the public preset and Skill services. PTC Plus resolves the official `cordis` preset through DSH's public preset service, lets the maintained filesystem provider read its Skill root as an immutable bundled Host resource, and filters that provider at the public registration boundary so sibling Skills are never published to the PTC scope. It does not copy the Skill or switch the agent's preset. The first request waits until the Cordis tool fiber, owner guidance, exact Skill provider, and scoped Skill load are all ready. An agent scope that omits one of those surfaces is left for later: the owner publishes nothing there, reports nothing, and retries when the tool surface changes or the next prompt is assembled. A scope whose exposed preset, Skill/tool service, declared Cordis service, inspect manifest, or activation contradicts the host contract fails the setting change at installation and removes every provisional contribution; reached through the host's own `agent/created` or assemble call it withdraws from that scope with one warning instead, so this plugin's unavailability never fails an agent another plugin created ([ADR 0029](adr/0029-keep-plugin-unavailability-out-of-the-host-agent-lifecycle.md)). Disable and agent/runtime disposal remove both fibers. Native agents inherit neither the resulting `tools.*` members nor the Skill, and the code-only direct-tool projection remains `[run_code]`. Cordis can evaluate model-written plugins against the live runtime, so enabling it grants shell-equivalent trust.
159
+ `cordisToolsEnabled: true` atomically mounts the official `@deepseek-ai/dsh-tool-cordis` plugin and exactly the selected official companion Skill in agent scopes that expose the `run_code` and `skill` tools plus the public preset and Skill services. PTC Plus resolves the official `cordis` preset through DSH's public preset service, lets the maintained filesystem provider read its Skill root as an immutable bundled Host resource, and filters that provider at the public registration boundary so sibling Skills are never published to the PTC scope. It does not copy the Skill or switch the agent's preset. The first request waits until the Cordis tool fiber, owner guidance, exact Skill provider, and scoped Skill load are all ready. An agent scope that omits one of those surfaces is left for later: the owner publishes nothing there, reports nothing, and retries when the tool surface changes or the next prompt is assembled. A scope whose exposed preset, Skill/tool service, declared Cordis service, inspect manifest, or activation contradicts the host contract fails the setting change at installation and removes every provisional contribution; reached through the host's own `agent/created` or assemble call it withdraws from that scope with one warning instead, so this plugin's unavailability never fails an agent another plugin created ([ADR 0029](adr/0029-keep-plugin-unavailability-out-of-the-host-agent-lifecycle.md)). Disable and agent/runtime disposal remove both fibers. Native agents inherit neither the resulting `tools.*` members nor the Skill, and the code-only direct-tool projection remains `[run_code]`. Cordis can evaluate model-written plugins against the live runtime, so enabling it grants shell-equivalent trust.
160
160
 
161
- The Skill root uses the preset's absolute composition path when that generation publishes one. A pathless generation is resolved through the active Host's public `pluginPackages.packageOf` service, which returns the official singular or plural preset package from that installation rather than an ambient package reachable from the plugin profile. An older generation with no such service may resolve only its historical plural package relative to the Host's `ctx.baseUrl`; the fallback is disabled whenever `pluginPackages` exists. The exact `cordis-plugin-development/SKILL.md` must exist before the mount begins. An invalid published path remains authoritative and fails instead of falling through to another generation's package layout.
161
+ The Skill root uses the preset's absolute composition path when that generation publishes one. A pathless generation is resolved through the active Host's public `pluginPackages.packageOf` service, which returns the official singular or plural preset package from that installation rather than an ambient package reachable from the plugin profile. An older generation with no such service may resolve only its historical plural package relative to the Host's `ctx.baseUrl`; the fallback is disabled whenever `pluginPackages` exists. The root must contain `dsh-doc/SKILL.md` or the historical `cordis-plugin-development/SKILL.md`; `dsh-doc` takes precedence when both exist. The selected official name and resource base remain intact through discovery, loading and readiness validation. An invalid published path remains authoritative and fails instead of falling through to another generation's package layout.
162
162
 
163
163
  Keep large Cordis host or client source in a top-level binding before calling a Cordis tool. If that call rejects while the worker stays live, an initialized binding can be reused in a short continuation. Decide whether to retry from the operation owner's retry/idempotence contract and available execution facts; a thrown call or a smaller cell does not prove that no effect occurred.
164
164
 
@@ -130,8 +130,8 @@ export const CONFIG_FIELDS = Object.freeze([
130
130
  type: 'enum',
131
131
  options: Object.freeze(['stateful', 'protected']),
132
132
  default: 'stateful',
133
- label: '跨 cell 声明策略',
134
- labelEn: 'Cross-cell declaration policy',
133
+ label: '绑定更新语义',
134
+ labelEn: 'Binding update semantics',
135
135
  description: '同一作用域的声明和赋值可更新变量、函数、类及导入。选“启用名称保护”时改为检测跨 cell 重声明,并保护新建的 const 和 import;静态 import/export 始终可用。',
136
136
  descriptionEn: 'Declarations and assignments update variables, functions, classes and imports in the same scope. With “Protect names” selected, cross-cell redeclarations are detected instead and newly created const and import bindings are protected; static import/export remains available.',
137
137
  },