dsh-ptc-plus 0.4.8 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/README.en.md +61 -123
  2. package/README.md +61 -123
  3. package/assets/dsh-ptc-plus-banner-en.webp +0 -0
  4. package/assets/dsh-ptc-plus-banner-zh.webp +0 -0
  5. package/assets/ptc-plus-repl-workspace-en.png +0 -0
  6. package/assets/ptc-plus-repl-workspace-zh.png +0 -0
  7. package/assets/ptc-plus-settings-en.png +0 -0
  8. package/assets/ptc-plus-settings-zh.png +0 -0
  9. package/client.cjs +42336 -0
  10. package/cordis.patch.yml +13 -2
  11. package/docs/README.md +7 -2
  12. package/docs/adr/0005-temporary-rejected-cell-edit-transport.md +31 -179
  13. package/docs/adr/0008-define-agent-operating-contract.md +5 -1
  14. package/docs/adr/0009-bound-expensive-acceptance-default.md +2 -2
  15. package/docs/adr/0016-archive-resolved-review-findings.md +1 -1
  16. package/docs/adr/0017-track-the-latest-dsh-public-surface.md +2 -2
  17. package/docs/adr/0019-plugin-settings-and-kill-switch.md +14 -3
  18. package/docs/adr/0020-optional-cordis-tools-in-ptc-mode.md +2 -2
  19. package/docs/adr/0022-stage-npm-releases-with-oidc.md +4 -2
  20. package/docs/adr/0023-global-user-bindings.md +3 -1
  21. package/docs/adr/0026-persist-the-delivery-verdict-against-the-verified-candidate.md +2 -0
  22. package/docs/adr/0028-attach-to-the-host-ptc-execution-seam.md +101 -35
  23. package/docs/adr/0030-serve-both-typert-codec-generations-from-one-codec.md +3 -3
  24. package/docs/adr/0031-close-semantic-obligations-by-owner.md +1 -1
  25. package/docs/adr/0032-own-session-log-facts-in-a-host-only-projection.md +27 -0
  26. package/docs/adr/0033-gate-client-visual-usability-in-a-browser.md +23 -0
  27. package/docs/adr/0034-keep-program-values-separate-from-output-projections.md +29 -0
  28. package/docs/adr/0035-run-coverage-only-before-a-new-release.md +27 -0
  29. package/docs/adr/0036-separate-focused-development-from-delivery-verification.md +29 -0
  30. package/docs/adr/0037-keep-tool-hover-previews-passive.md +52 -0
  31. package/docs/adr/0038-freeze-session-capability-plans.md +71 -0
  32. package/docs/adr/0039-verify-documentation-without-runtime-suites.md +29 -0
  33. package/docs/adr/0040-separate-capability-configurations-from-session-observations.md +39 -0
  34. package/docs/adr/0041-record-cell-execution-directories.md +65 -0
  35. package/docs/adr/0042-persist-provider-availability-and-handback.md +41 -0
  36. package/docs/adr/0043-compose-capability-and-context-policies.md +37 -0
  37. package/docs/adr/README.md +6 -0
  38. package/docs/architecture.md +25 -27
  39. package/docs/binding-review-placement-design.md +29 -21
  40. package/docs/capability-planning-components.md +93 -0
  41. package/docs/capability-projection.md +7 -0
  42. package/docs/client-ui.md +88 -29
  43. package/docs/client-visual-contract.md +65 -0
  44. package/docs/context-management.md +22 -0
  45. package/docs/context-optimization-plan.md +353 -0
  46. package/docs/context-public-interface-coverage.md +25 -0
  47. package/docs/durability-design.md +31 -14
  48. package/docs/evaluation.md +41 -6
  49. package/docs/evaluations/command-goat-deepseek-v4.1-flash-20261006.md +126 -0
  50. package/docs/evaluations/command-goat-deepseek-v4.1-flash.md +281 -0
  51. package/docs/installation.md +50 -8
  52. package/docs/program-data-plane.md +5 -3
  53. package/docs/publishing.md +5 -5
  54. package/docs/release-coverage.md +73 -0
  55. package/docs/release-notes.md +1 -1
  56. package/docs/review-procedure.md +56 -0
  57. package/docs/runtime-reference.md +48 -16
  58. package/docs/semantic-validation.md +14 -2
  59. package/docs/stateful-binding-updates-proposal.md +2 -2
  60. package/docs/user-bindings.en.md +2 -2
  61. package/docs/user-bindings.md +3 -3
  62. package/docs/value-wire.md +11 -1
  63. package/docs/verification-optimization-work.md +52 -15
  64. package/docs/verification.md +30 -86
  65. package/index.js +147 -23
  66. package/internal/binding-toggle-receipt.js +24 -0
  67. package/internal/capability-command-receipt.js +29 -0
  68. package/internal/capability-environment.js +1247 -0
  69. package/internal/capability-plan.js +285 -0
  70. package/internal/capability-policy.js +96 -0
  71. package/internal/capability-statistics-store.js +180 -0
  72. package/internal/capability-statistics.js +210 -0
  73. package/internal/compiler-platform.js +5 -3
  74. package/internal/compiler-service.js +2 -9
  75. package/internal/config-spec.js +79 -9
  76. package/internal/cordis-tools-owner.js +22 -19
  77. package/internal/direct-surface-owner.js +29 -29
  78. package/internal/dynamic-environment-runtime.js +9 -9
  79. package/internal/edit-transport-owner.js +183 -139
  80. package/internal/execution-provider-owner.js +160 -0
  81. package/internal/execution-seam-compat.js +76 -120
  82. package/internal/isolated-worker.js +12 -8
  83. package/internal/kernel-worker.js +104 -32
  84. package/internal/native-root-dynamic.js +12 -13
  85. package/internal/program-bindings.js +190 -0
  86. package/internal/recovery-tips.js +53 -23
  87. package/internal/rejected-cell-editor.js +8 -8
  88. package/internal/repl-observation-interest.js +11 -3
  89. package/internal/rpc-contract.js +1 -0
  90. package/internal/runtime-bridge-owner.js +351 -82
  91. package/internal/runtime-config.js +58 -0
  92. package/internal/runtime-contexts.js +85 -16
  93. package/internal/runtime-intrinsics.js +1 -0
  94. package/internal/runtime-messages.js +41 -0
  95. package/internal/sdk-projection.js +10 -82
  96. package/internal/session-cell-executor.js +42 -19
  97. package/internal/session-events.js +74 -4
  98. package/internal/session-journal-recovery.js +904 -184
  99. package/internal/session-journal-schema.js +6 -3
  100. package/internal/session-journal.js +31 -2
  101. package/internal/session-log-view.js +189 -43
  102. package/internal/session-runtime.js +175 -23
  103. package/internal/settings-compat.js +23 -6
  104. package/internal/stateful-module-compiler.js +3 -2
  105. package/internal/stateful-module-runtime.js +7 -3
  106. package/internal/stateful-root-runtime.js +9 -4
  107. package/internal/user-binding-authoring.js +2 -7
  108. package/internal/user-bindings-owner.js +47 -7
  109. package/internal/validated-parse-repair.js +1 -1
  110. package/internal/value-wire.js +68 -21
  111. package/internal/worker-cwd-virtualization.js +20 -18
  112. package/internal/worker-realm-surfaces.js +3 -3
  113. package/locale/en.json +6 -0
  114. package/locale/zh.json +6 -0
  115. package/package.json +55 -38
  116. package/src/client-authoring-view.js +286 -168
  117. package/src/client-binding-review.js +4 -1
  118. package/src/client-binding-toggle.js +18 -0
  119. package/src/client-capabilities-view.js +1341 -0
  120. package/src/client-capability-sort.js +29 -0
  121. package/src/client-code-editor.js +6 -0
  122. package/src/client-copy.js +881 -8
  123. package/src/client-feature-gates.js +15 -5
  124. package/src/client-host-compat.js +23 -2
  125. package/src/client-indicator-view.js +4 -6
  126. package/src/client-primitives.js +280 -0
  127. package/src/client-repl-view.js +23 -16
  128. package/src/client-settings-view.js +412 -69
  129. package/src/client-styles.js +193 -41
  130. package/src/client-tool-hover.js +185 -0
  131. package/src/client-tool-view.js +45 -11
  132. package/src/client-transport.js +44 -9
  133. package/src/client-workbench.js +9 -10
  134. package/src/client.js +148 -68
  135. package/assets/ptc-plus-bindings-en.png +0 -0
  136. package/assets/ptc-plus-bindings-zh.png +0 -0
  137. package/assets/ptc-plus-repair-en.png +0 -0
  138. package/assets/ptc-plus-repair-zh.png +0 -0
  139. package/client.js +0 -31857
@@ -4,6 +4,8 @@
4
4
 
5
5
  Each top-level `run_code` executes a JavaScript/TypeScript cell with top-level `await`, ordinary control flow and a session root that continues across cells. Static import/export syntax is part of the language. TypeScript runtime forms such as enums and namespaces are transformed before execution. Returned and printed values form the result; binding state is independent of its presentation.
6
6
 
7
+ The direct tool schema identifies a PTC TypeScript cell; the selected language guidance owns its conventions and restrictions. It does not describe internal async lowering as a source grammar. Stable guidance places direct Node module computation at the execution entry, while retaining external processes for tasks that require their environment or an independent engine.
8
+
7
9
  With the default `bindingUpdates: 'stateful'`, declarations and assignments update one logical identity in the same scope and activation, including local const bindings. An existing closure observes later updates, while a saved function value keeps its own identity. Separate block, function and iteration scopes stay separate. A bare `let x`, `var x` or `const x` preserves an existing value and creates undefined when new. Each declarator publishes its complete candidate only after its initializer and binding pattern succeed. Earlier declarators and ordinary assignment effects remain real if a later operation fails. Unreached lexical declarations do not reserve a name for future cells.
8
10
 
9
11
  An import alias follows its module until an actual successful assignment or declaration supplies a local value. A static import in a later cell switches that same identity back to the module, so existing new-generation closures observe the change. Within one cell, all static imports install their sources before the body; an ordinary declaration or assignment in the body can override them regardless of where the import appears in the text. Named default declarations associate `__default` with the local identity until independently overwritten. Static dependencies link before the body and keep their effects even if a later dependency fails.
@@ -16,13 +18,15 @@ Each session kernel owns one native Node realm. Cells, PTC-managed modules, the
16
18
 
17
19
  Every program namespace is leased to one cell. Namespace objects or member functions captured in the REPL expire when that cell ends. A reusable REPL helper must look up the current namespace inside its body. Global User Binding modules use a dynamic bridge: even a module-captured member resolves the current implementation when invoked by a new cell; a removed member fails until it is available again. Continuations retain their originating cell identity and cannot borrow a later cell's lease.
18
20
 
19
- For PTC mode requests using the code-only direct-tool projection, PTC Plus presents two tools in stable order: `run_code` and `edit_run_code`. It recognizes the current Host's `tools:ptc-only` owner section and the preceding Host's `tools:code-only` alias, with the current section authoritative if both appear. The latter tool edits the most recent eligible cell visible when the edit call is dispatched, including a cell that completed successfully but needs a small adjustment. That target remains fixed while the call is in flight; later tool settlements cannot retarget it. The edit accepts exactly one atomic `edits` or `regex_edits` array and an optional `expected_target_call_seq` precondition. Invalid, unavailable, or mismatched-target edits return `{ edited: false, reason }` without executing source or consuming the target. `regex_edits[].replacement` is a JavaScript replacement template: captures are referenced as `$1`, `$2`, ... or `$<name>`, a literal dollar sign is written `$$`, and backslash forms such as `\1` are emitted literally rather than resolved as captures. `pattern` values are JavaScript regular-expression sources without delimiters.
21
+ Official PTC mode declares only top-level `run_code`. PTC Plus registers `edit_run_code` in the program SDK before the first model request. Call `tools.edit_run_code` inside a cell. Actual derived `run_code` dispatches have their own recorded start/settle events and retain the live root transport as their parent. The private root evidence distinguishes the editor cause (`startSeq`) from derived execution identity (`executionStartSeq`); the latter identifies the published revised cell. See [ADR 0005](adr/0005-temporary-rejected-cell-edit-transport.md) for its settlement and recovery contract.
22
+
23
+ The editor captures the most recent eligible cell when its official nested dispatch starts, including a successful cell that needs a small adjustment. The target remains fixed while the call is in flight. It accepts exactly one atomic `edits` or `regex_edits` array and an optional `expected_target_call_seq` guard. Invalid, unavailable or mismatched-target edits return `{ accepted: false, scheduled: false, reason }` without executing source. Regex replacement uses JavaScript `$1`, `$<name>` and `$$` templates; backslash forms such as `\\1` remain literal. Every regex item requires `pattern`, `flags`, `replacement` and `expected_matches`, including an explicit `""` flags string when no flags are needed.
20
24
 
21
- `edit_run_code` is a real registered tool call. Session history and later model requests retain its original name and delta arguments. The plugin executes the materialized source as a host-derived `run_code`, returns only the edit status, value, and logs to the model, and keeps the complete source plus journal in private replay metadata. It does not rewrite assistant history or emit edit-specific runtime context.
25
+ An accepted nested editor call returns `{ accepted: true, scheduled: true, target_call_seq }`. This is a scheduling receipt. The outer cell continues with its current state and original return value or error; after it finishes, PTC Plus dispatches the complete revised source through DSH's real `run_code` tool pipeline before settling the root result. The root result retains the outer canonical value or error and forwards the derived result's Host-rendered content, images, additional contexts and, for a successful root result, turn-conclusion flag; the next cell sees revised bindings. Official nested dispatch events retain editor identity and arguments. Private root-result metadata retains the derived source and journal for cold recovery without rewriting assistant history or emitting edit-specific runtime context. Rejecting the nested receipt prevents dispatch; losing root metadata after derived execution instead invalidates recovery evidence and does not undo effects. When the public Host skips the nested metadata projector, PTC Plus may retain private derived evidence only if its exact pre-policy frozen canonical value survives final policy with unchanged base metadata and execution identity. Block/error, value replacement, missing capture or removal of projected metadata rejects that evidence. The Host result remains unchanged; see [Derived journal settlement](durability-design.md#两阶段确认).
22
26
 
23
- One provider failure has a bounded transport recovery. When the provider reports the exact invalid-tool-JSON `MALFORMED_RESPONSE` as a terminal chunk or stream exception, PTC Plus changes that terminal reason to `tool-calls`; this error cannot terminate the whole turn. DSH already preserves an unparseable argument string and routes it through ordinary validation, tool execution/result recording, and the next model step. A response is trusted for call preservation only when its buffered body consists entirely of tool-call-specific framing plus at most one `usage` event. If such a response contains exactly one internally consistent declared `run_code` or `edit_run_code` block, PTC Plus also tests deletion of one final `}`. It applies that correction only when the resulting value is an object accepted by the live direct-tool schema. The call keeps its index, identity, and name and proceeds through ordinary DSH validation, recording, scheduling, authority, and execution. Without a unique correction, trusted internally consistent complete blocks retain their original identity and argument bytes for the ordinary rejected-tool-result path; PTC Plus re-emits canonical start/delta/end framing so every tolerated provider variant passes DSH's stream invariant. If a tool block is incomplete or inconsistent, none was emitted, multiple usage events appear, or any other event occurs in the buffered body, PTC Plus closes any already visible text or reasoning block from its accumulated content, removes buffered unsafe block material, and emits one deterministic `run_code` call whose argument string cannot parse as a JSON object. DSH rejects it during ordinary schema validation, so no partial model call executes and the model still receives another step. Valid streams and other provider failures retain their original result. This is not a general JSON repair mechanism.
27
+ One provider failure has a bounded transport recovery. When the provider reports the exact invalid-tool-JSON `MALFORMED_RESPONSE` as a terminal chunk or stream exception, PTC Plus changes that terminal reason to `tool-calls`; this error cannot terminate the whole turn. DSH already preserves an unparseable argument string and routes it through ordinary validation, tool execution/result recording, and the next model step. A response is trusted for call preservation only when its buffered body consists entirely of tool-call-specific framing plus at most one `usage` event. If such a response contains exactly one internally consistent declared `run_code` block, PTC Plus also tests deletion of one final `}`. It applies that correction only when the resulting value is an object accepted by the live direct-tool schema. The call keeps its index, identity, and name and proceeds through ordinary DSH validation, recording, scheduling, authority, and execution. Without a unique correction, trusted internally consistent complete blocks retain their original identity and argument bytes for the ordinary rejected-tool-result path; PTC Plus re-emits canonical start/delta/end framing so every tolerated provider variant passes DSH's stream invariant. If a tool block is incomplete or inconsistent, none was emitted, multiple usage events appear, or any other event occurs in the buffered body, PTC Plus closes any already visible text or reasoning block from its accumulated content, removes buffered unsafe block material, and emits one deterministic `run_code` call whose argument string cannot parse as a JSON object. DSH rejects it during ordinary schema validation, so no partial model call executes and the model still receives another step. Valid streams and other provider failures retain their original result. This is not a general JSON repair mechanism.
24
28
 
25
- When a live parse error occurs exactly at the cell EOF, PTC Plus checks all 12 suffixes of one or two closing tokens drawn from `}`, `)`, and `]` with the same preparation context. If exactly one correction succeeds, the existing editor can express it from a bounded unique suffix, and the rejected call has a persistent event identity, `PTC-C001` includes a directly callable `edit_run_code({ edits: [...], expected_target_call_seq })` invocation. The guard must match the target captured when the edit call is persisted, so a later editable cell suppresses execution even when the same literal replacement would match it. The plugin does not apply or execute the correction automatically; ambiguous, broader, and unbound repairs keep the ordinary length-adaptive guidance.
29
+ When a live parse error occurs exactly at the cell EOF, PTC Plus checks all 12 suffixes of one or two closing tokens drawn from `}`, `)`, and `]` with the same preparation context. If exactly one correction succeeds, the existing editor can express it from a bounded unique suffix, and the rejected call has a persistent event identity, `PTC-C001` includes `await tools.edit_run_code({ edits: [...], expected_target_call_seq })` for use inside a new `run_code` cell. The guard must match the target captured when the edit call is persisted, so a later editable cell suppresses execution even when the same literal replacement would match it. The plugin does not apply or execute the correction automatically; ambiguous, broader, and unbound repairs keep the ordinary length-adaptive guidance. A parse-rejected derived edit does not publish its attempted source as an editable target, so its diagnostic keeps that general guidance rather than attaching a guard for the different outer root source. Published derived cells remain editable through their own recorded source identity.
26
30
 
27
31
  Use `return` for an explicit result and the native Node `console` surface for logs. Its formatting methods, including `dir` options, tables, counters, groups, timers, assertions, and traces, retain Node semantics. `process.stdout/stderr.write`, direct fd 1/2 writes and inherited child stdio are also captured. Console entries retain call order and each descriptor pipe retains byte order; the merged log does not claim a total chronology across stdout, stderr and the private control channel. All forms share the cell's aggregate output budget. Native expression completion can also supply a result value:
28
32
 
@@ -37,9 +41,13 @@ Each physical cell has acknowledged start and end fences on stdout and stderr. D
37
41
 
38
42
  Prefer executing work directly in the current cell; reserve `code.run` for source already held as data. When nested source must be written inline, escape quotes, backslashes, and newlines exactly — its parse errors point only at the generated text, not at a position in the outer cell.
39
43
 
44
+ For stateful/protected cells, the public prompt assembly projects the Host SDK introduction to describe runtime TypeScript `enum` and namespaces. Only the known cell-grammar phrase is replaced; native tool declarations and their guidance remain unchanged. Legacy cells keep the Host erasable-syntax restriction. Explicit `eval` and `Function` retain their native JavaScript syntax targets.
45
+
40
46
  ## Capability Discovery
41
47
 
42
- The default SDK declares `capabilities.tree/find/inspect` directly, so exploring the explorer's own contract is unnecessary. `find` uses case-insensitive lexical matching, prioritizing exact `namespace.member` symbols, namespace names, and member names before complete identifier or description tokens. CamelCase and punctuation separate tokens; multiple query tokens must be contiguous. Prefer a short query such as `read` over a prose request such as `read file content`. A miss means no lexical match, not proof that a capability is unavailable.
48
+ The default SDK declares `capabilities.tree/find/inspect/search` directly. `search({ query, budgetBytes?, limit?, cursor? })` retrieves complete indexed descriptions with parameters, return schemas and available metadata in one response. It matches non-contiguous English/Chinese terms, prioritizes exact symbols and names, and supplies catalog/query-bound continuation. The default is 16384 UTF-8 serialized JSON bytes and 10 considered matches per page; the minimum budget is 512 bytes. `usedBytes` includes the entire JSON envelope and oversized references, excluding outer `run_code` rendering. A contract that cannot fit is explicitly listed in `oversized` with an `inspect` reference; it is never truncated to look complete. This is lexical retrieval, not semantic inference or access to undisclosed services. See [Capability Surface](capability-projection.md) for the response boundary.
49
+
50
+ The compatible `find` uses case-insensitive lexical matching, prioritizing exact `namespace.member` symbols, namespace names, and member names before complete identifier or description tokens. CamelCase and punctuation separate tokens; multiple query tokens must be contiguous. A miss means no lexical match, not proof that a capability is unavailable. `tree` and item-budgeted `inspect` keep their existing unbounded-byte interfaces. With capability management enabled, the SDK section is re-rendered from the frozen session plan: Host-declared members keep their Host schemas, complete and on-demand contracts arrive through session messages, and the always-callable `edit_run_code` transport keeps its Host signature in every render. Settings changes affect new sessions; `/capabilities refresh` synchronizes an existing session. See [public integration evidence](context-public-interface-coverage.md).
43
51
 
44
52
  `tree()` returns namespace entries whose `members` are strings, not a flat symbol list. Form symbols with `tree.flatMap(entry => entry.members.map(member => `${entry.namespace}.${member}`))`. Reuse an observed tree within the current capability view and inspect only relevant symbols; do not infer completeness or effect guarantees from discovery. Exact symbols in examples are conditional on the live view. The advanced `repl.state` and `code.run` schemas remain behind inspection:
45
53
 
@@ -53,10 +61,28 @@ return capabilities.inspect({
53
61
 
54
62
  Discovery covers current `tools` plus the advanced `repl` and `code` namespaces. It is read-only and does not grant authority. Calls still use the typed member declared by the capability owner. Use ordinary Node.js and current-cell `tools.*` directly; reserve isolated `code.run` for source already held as data.
55
63
 
56
- For commands, prefer project-declared scripts and use an available typed tool. When direct host process access is more appropriate, inspect the executable that is actually installed and invoke it through Node.js `child_process`. Child processes inherit the recorded session cwd when `options.cwd` is omitted, while an explicit `cwd` remains authoritative; the worker preserves the host execution environment needed to resolve package runners and shells. Add a shell or package runner only when the command requires its syntax or resolution; do not assume a particular shell exists.
64
+ For commands, prefer project-declared scripts and use an available typed tool. When direct host process access is more appropriate, inspect the executable that is actually installed and invoke it through Node.js `child_process`. Child processes inherit the recorded cell execution cwd when `options.cwd` is omitted, while an explicit `cwd` remains authoritative; the worker preserves the host execution environment needed to resolve package runners and shells. Add a shell or package runner only when the command requires its syntax or resolution; do not assume a particular shell exists.
57
65
 
58
66
  ## Configuration
59
67
 
68
+ Capability management is experimental and defaults to off. These inputs are frozen per session; saved changes apply to new sessions or `/capabilities refresh`:
69
+
70
+ | Field | Default | Meaning |
71
+ | --- | --- | --- |
72
+ | `capabilityContextEnabled` | `true` | Pause rules, collection, recovery and plugin previews together without changing saved child settings; applies on new session or refresh |
73
+ | `capabilityManagementEnabled` | `false` | Enable capability planning and projection |
74
+ | `capabilityBaseline` | `'[]'` | JSON array of common capability identities |
75
+ | `capabilityPolicy` | host disclosure, enabled availability, baseline/budget allocation selected, statistics allocation off | Independent default/category/MCP-source/item rules and allocation inputs; [ADR 0043](adr/0043-compose-capability-and-context-policies.md) |
76
+ | `capabilityOverrides` | `'{}'` | Legacy JSON choices migrated when no capabilityPolicy is supplied |
77
+ | `capabilityStatistics` | `'{"enabled":false,"windowSize":100,"minimumSamples":10,"fullThreshold":0.5}'` | Independent collection and family coverage settings; policy allocation.statistics separately consumes evidence |
78
+ | `capabilityProfiles` | `{"schema":"ptc-capability-profiles/v1","profiles":[]}` | Up to 100 named reusable capability configurations; structured UI save/import/export/switch, separate from frozen session plans; [ADR 0040](adr/0040-separate-capability-configurations-from-session-observations.md) |
79
+ | `capabilityBudgetBytes` | `16384` | Full-contract budget in UTF-8 bytes, minimum 1 |
80
+ | `capabilityDirectoryBytes` | `2048` | Navigation budget in UTF-8 bytes, minimum 512 |
81
+ | `capabilityRecoveryEnabled` | `false` | Select optional description recovery independently |
82
+ | `capabilityRecoveryBytes` | `8192` | Separate description-recovery budget in UTF-8 bytes, minimum 1 |
83
+ | `modelPreviewEnabled` | `false` | Select plugin result/log previews; otherwise delegate to the Host policy |
84
+ | `modelPreviewTokens` | `4096` | Estimated model-presentation token cap, minimum 1 |
85
+
60
86
  The configuration uses `ptc-plus` as the DSH plugin ID and `dsh-ptc-plus` as the package name. The distinction is intentional: the former is the runtime/settings identity, while the latter is the repository and npm package identity.
61
87
 
62
88
  `enhancedToolView` defaults to `true` and controls only the browser presentation of `run_code` and `edit_run_code`. Turning it off unregisters PTC Plus's keyed tool views so DSH's native generic row renders the calls; turning it on restores the compatibility renderer without changing execution, prompt, or session behavior.
@@ -93,9 +119,9 @@ Missing-description diagnostics append a complete DSH user message to `additiona
93
119
 
94
120
  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.
95
121
 
96
- `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. Every setting is applied live when its owner can reconcile it. A submitted cell retains one configuration snapshot through preflight, execution, binding calls, completion validation, and diagnostics; an update accepted while it runs applies to cells submitted afterward. Node fixes a worker's V8 old-generation limit at creation, so changing `maxOldGenerationSizeMb` while a session worker is active 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)) — shows “已启用” or “已停用”, and disables every control except `enabled` 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.
122
+ `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. A submitted cell retains one configuration snapshot through preflight, execution, binding calls, completion validation, and diagnostics; an update accepted while it runs applies to cells submitted afterward. 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.
97
123
 
98
- `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, edit_run_code]`. Cordis can evaluate model-written plugins against the live runtime, so enabling it grants shell-equivalent trust.
124
+ `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.
99
125
 
100
126
  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.
101
127
 
@@ -135,15 +161,15 @@ With `durableReplay: true`, recovery claims only bindings backed by both verifie
135
161
 
136
162
  An invalid historical association, prune replacement, or recovery boundary is also rejected as evidence for its bindings; it is not by itself a reason to reject every later valid `run_code`. Recovery takes the intersection of the model-knowable and structurally verified frontiers, then discards cells and bindings that may depend on an unknown boundary. Because the current journal does not contain a complete per-binding dependency graph, the conservative unit is an affected cell and suffix unless stronger owned evidence exists. If no non-empty frontier is provable, the worker starts from an empty REPL and executes the current cell as a new root.
137
163
 
138
- The first continued cell reports `PTC-R002` once so the model can redeclare any missing bindings, and its result persists the contraction for later cold starts. Recovery never redispatches, reverses, or certifies effects from discarded history. This availability fallback applies only to historical PTC Plus recovery data; validation, policy, authority, approval, cancellation, and other failures of the current request retain their normal DSH behavior.
164
+ The first continued cell reports `PTC-R002` so the model can redeclare any missing bindings. Consecutive contractions share one full notice while every result still persists its actual contraction for later cold starts. A cell that proceeds without recovery ends that notice episode. On failure, recovery guidance accompanies the primary error; captured output contains the cell's console output. Delegated sessions read their own public DSH observation and ordered surface, independently of the parent execution context. Recovery never redispatches, reverses, or certifies effects from discarded history. This availability fallback applies only to historical PTC Plus recovery data; validation, policy, authority, approval, cancellation, and other failures of the current request retain their normal DSH behavior.
139
165
 
140
166
  PTC dynamic messages carry `source: { kind: 'plugin:ptc-plus', form: 'snapshot' | 'catalog' | 'notice' }`. Current-state snapshots replace only earlier PTC state, including historical PTC aggregate sections; they do not replace the binding API catalog, tasks, Skill instructions, tool results, or other producers. Only a later binding catalog replaces an earlier catalog, and an explicit empty catalog withdraws its API documentation. Host runtime-context clearance does not invalidate the catalog; suppression gates new delivery. Empty snapshots withdraw earlier state claims. Delivery uses the public accepted pre-step decision and honors `includeRuntimeContext`, scoped suppression, and cancellation through an empty assembly witness. Committed messages and the public ordered surface drive deduplication and reconciliation after compaction or resume. Proposals do not count as delivery; raw history does not establish model knowledge.
141
167
 
142
168
  Recovery tips are disabled with `tipsEnabled: false`. When enabled, a bounded independent PTC notice identified by `tools:ptc-plus-tip/<trigger>/<ordinal>` may appear after a repeated binding failure or a diagnostic that identifies an executable, shell, or path problem in the current execution world. The trigger and per-trigger ordinal are reconstructed from committed PTC notices and canonical historical DSH snapshot sections; each identity counts once across both sources, and visible wording does not advance history. A tip is subject to `tipCooldownMessages` and becomes detailed only after `tipEscalationFailures` unresolved matches; it never changes the code-only direct-tool list or schema. `edit_run_code` does not emit a runtime context because its real call and result already carry the relevant fact.
143
169
 
144
- Static and dynamic imports retain Node's resolver from the session cwd, falling back to the worker cwd when none was recorded. Relative files, bare packages, conditional exports, URLs and attributes retain their Node meaning. A missing requested export fails at static linking before that target module evaluates. Namespace property writes still follow the namespace object's own contract; updating an alias does not mutate the namespace. A managed namespace's members are readonly: a member write is refused and leaves the member's live value unchanged, while reflection continues to report that live value. `Reflect.set` returns `false`, and `Object.defineProperty` with a different value throws `TypeError`; a direct assignment from a non-strict cell body is silently discarded, exactly as for any other readonly property.
170
+ Each new cell uses DSH's resolved current directory for Node resolution. Relative filesystem, path and default child-process operations use the cell's current directory at the time they run: a confirmed in-cell `tools.working_directory` result rebases the rest of that cell, so the cell and the Host tools resolve against the same directory, and the recorded call carries the transition while the journal keeps the cell's starting directory. Captured import/require functions, synthetic `import.meta` and loaded modules retain their source bases. Cold replay uses each cell's recorded directory and settles a recorded in-cell change from its journal entry; predecessor journals retain the original header/worker fallback ([ADR 0041](adr/0041-record-cell-execution-directories.md)). Relative files, bare packages, conditional exports, URLs and attributes retain their Node meaning. A missing requested export fails at static linking before that target module evaluates. Namespace property writes still follow the namespace object's own contract; updating an alias does not mutate the namespace. A managed namespace's members are readonly: a member write is refused and leaves the member's live value unchanged, while reflection continues to report that live value. `Reflect.set` returns `false`, and `Object.defineProperty` with a different value throws `TypeError`; a direct assignment from a non-strict cell body is silently discarded, exactly as for any other readonly property.
145
171
 
146
- Current `stateful-v1` and `protected-v1` cells expose one mutable, null-prototype `import.meta` object per cell. Its `url` is the file URL of the synthetic `<session cwd>/repl` parent, `filename` is that synthetic path, and `dirname` is the recorded session cwd; when no cwd was recorded, all three use the worker cwd. Relative `new URL(..., import.meta.url)`, static import, dynamic import and provided `require` therefore start from the same parent. Frozen `legacy-v1` cells retain their historical `import.meta` parse rejection. Cell source otherwise has a deliberate CommonJS-like subset: `require`, `require.resolve` and `require.cache` exist; `require.main` is `undefined`; ambient `__dirname`, `__filename` and `module` do not exist. Use `import.meta.dirname`, `import.meta.filename` and `import.meta.url` for cell path metadata.
172
+ Current `stateful-v1` and `protected-v1` cells expose one mutable, null-prototype `import.meta` object per cell. Its `url` is the file URL of the synthetic `<cell execution cwd>/repl` parent, `filename` is that synthetic path, and `dirname` is the recorded cell execution cwd; when no cwd was recorded, all three use the worker cwd. Relative `new URL(..., import.meta.url)`, static import, dynamic import and provided `require` therefore start from the same parent. Frozen `legacy-v1` cells retain their historical `import.meta` parse rejection. Cell source otherwise has a deliberate CommonJS-like subset: `require`, `require.resolve` and `require.cache` exist; `require.main` is `undefined`; ambient `__dirname`, `__filename` and `module` do not exist. Use `import.meta.dirname`, `import.meta.filename` and `import.meta.url` for cell path metadata.
147
173
 
148
174
  Cell export modifiers retain local declarations; remote re-exports retain dependency loading, type-only exports are erased, and default values use the ordinary `__default` identity. Real modules expose their actual export names through a stable PTC-managed namespace. Member reads follow live sources until actual local override and return original function/object values. A namespace retained by an external function continues to provide live reads. Its readonly properties do not make it a native module namespace object. Opaque code independently using native import on the raw compiled URL, or its own native createRequire, can see the transport representation and does not receive PTC's writable-export interface. PTC-provided imports and require, binding modules, workbench commands and `code.run` children share the managed interface with independent state and lifecycle. The complete contract and acceptance conditions belong to [ADR 0025](adr/0025-use-versioned-logical-binding-identities.md#managed-module-interface).
149
175
 
@@ -161,7 +187,7 @@ Rewrites are recorded as `meta.dshPtcPlusRewrites` on the tool result (parallel
161
187
 
162
188
  | Code | Meaning | State effect |
163
189
  | --- | --- | --- |
164
- | `PTC-C001` | The cell cannot be parsed | Not executed; REPL unchanged; a uniquely validated and target-bound one- or two-token EOF closure includes a directly callable declared `edit_run_code` repair; otherwise retry a short corrected cell with `run_code`, use edit for a localized long-cell correction, and resend with `run_code` for broad, ambiguous, or unbound repairs |
190
+ | `PTC-C001` | The cell cannot be parsed | Not executed; REPL unchanged; a uniquely validated and target-bound one- or two-token EOF closure includes an `await tools.edit_run_code(...)` repair for a new `run_code` cell; otherwise retry a short corrected cell with `run_code`, use edit for a localized long-cell correction, and resend with `run_code` for broad, ambiguous, or unbound repairs |
165
191
  | `PTC-C002` | Preflight rejected a kernel-control import | Not executed; REPL unchanged |
166
192
  | `PTC-N001` | Top-level binding conflict | Not executed; REPL unchanged |
167
193
  | `PTC-O001` | Unsupported or over-budget output | Cell executed; earlier mutations may exist |
@@ -170,19 +196,21 @@ Rewrites are recorded as `meta.dshPtcPlusRewrites` on the tool result (parallel
170
196
  | `PTC-W001` | The same cell failed 3 consecutive times with an identical binding error | Supplemental warning carries the primary failure's conservative state effect, or `unknown` when unavailable |
171
197
  | `PTC-W002` | The same cell failed 3 consecutive times with another identical error | Supplemental warning carries the primary failure's conservative state effect, or `unknown` when unavailable |
172
198
 
199
+ Generic stateful/protected exception help does not infer an initializer failure from the language generation. Completed declarations and actual assignments remain live; continue with the same names according to execution facts and the selected update policy, inspecting relevant values when their state is uncertain.
200
+
173
201
  Durability describes recovery after a kernel restart; it does not certify that a failed cell is safe to execute again. A failing cell can mutate bindings or produce an external effect before the exception. Continuation follows the operation owner's retry/idempotence contract and available execution facts; there is no universal status-query prerequisite. Host tool calls restore the DSH initiator boundary, so tools that require the exact live calling agent work through `tools.*`.
174
202
 
175
203
  Repeated lexical errors direct the model to visible source, scope, and initialization. Worker-owned lease failures direct continuation to the current namespace; proved missing members recommend capability discovery. Error text cannot impersonate that provenance. The warning threshold is three consecutive identical failures, independently of tip cooldown and escalation. Platform tips consume bounded multiline message/stderr facts when no structured owner cause exists; a generic command exit alone does not establish a platform error.
176
204
 
177
205
  Cold replay reuses validated recorded `PTC-X001` and `PTC-O001` diagnostic wording for the same actual failure before comparing the complete completion and transcript. Historical help text therefore cannot discard otherwise verified bindings merely because current guidance changed. A real failure-message, completion, or transcript mismatch still contracts recovery; no historical call is redispatched.
178
206
 
179
- Known top-level native calls outside the declared direct surface may be normalized into `run_code` when the live schema proves the intended tool. The canonicalizer parses arguments once: ordinary JSON is embedded as JavaScript, while values with own `__proto__` keys use safe literals, so the derived cell needs no `JSON.parse` and keeps execution semantics. The normalization adds no provenance or correction text visible to the model. Unknown, malformed, or internally inconsistent calls remain on the DSH host diagnostic path. The two declared direct tools, `run_code` and `edit_run_code`, are never renamed by this recovery path.
207
+ Known top-level native calls outside the declared direct surface may be normalized into `run_code` when the live schema proves the intended tool. The canonicalizer parses arguments once: ordinary JSON is embedded as JavaScript, while values with own `__proto__` keys use safe literals, and JSON beyond the TypeScript parser safety depth uses a shallow `JSON.parse` expression, preserving execution semantics. The normalization adds no provenance or correction text visible to the model. Unknown, malformed, or internally inconsistent calls remain on the DSH host diagnostic path. The declared direct `run_code` keeps its identity. The nested editor is called through `tools.edit_run_code` and never obtains admission through this recovery path.
180
208
 
181
209
  Inside a cell, omitting the JavaScript argument of a native `tools` member is accepted only when DSH's live object schema validates `{}`. The worker canonicalizes that omission to `{}` before encoding, so dispatch, the durable call transcript, and cold replay observe the same arguments. This supports natural calls such as `tools.cordis_inspect_list()` without a tool-name exception. Passing `undefined` explicitly, omitting required input, or calling another program namespace retains its existing behavior.
182
210
 
183
211
  ## Named State
184
212
 
185
- `capabilities.inspect({ symbols: ['repl.state'] })` exposes the optional state API and its timing contract. A save/restore/delete return value acknowledges an accepted operation. Save checkpoints the final settled cell frontier, not the statement where `save` was called. Restore takes effect after settlement for the next cell; reads and writes after awaiting restore still use the current cell's state. Tentative saves can be discarded when the cell becomes volatile or discarded. These operations neither reverse external effects nor certify retry safety.
213
+ `capabilities.inspect({ symbols: ['repl.state'] })` exposes the optional state API and its timing contract. A save/restore/delete return value acknowledges an accepted operation. Save checkpoints the final settled cell frontier, not the statement where `save` was called. Restore takes effect after settlement for the next cell; reads and writes after awaiting restore still use the current cell's state. Tentative saves can be discarded when the cell becomes volatile or discarded. A volatile save rejection reports the recorded reason and leaves live bindings usable. Restore discards state beyond the selected durable frontier; an unnamed restore selects the prior durable head, or an empty REPL when none exists. It does not change enabled global binding configuration, and subsequent cells can remain volatile because of those inputs or disabled durable replay. Restore therefore does not guarantee that saving will become possible. These operations neither reverse external effects nor certify retry safety.
186
214
 
187
215
  ## Limits
188
216
 
@@ -190,11 +218,15 @@ Inside a cell, omitting the JavaScript argument of a native `tools` member is ac
190
218
 
191
219
  - The runtime is identified as `typescript`. Stateful and protected cells erase type-only syntax and lower enums, namespaces, parameter properties, and decorators through maintained TypeScript and decorator transforms. JSX is outside the cell syntax. Historical cells retain their recorded language generation.
192
220
  - `tools.read` is a bounded inspection window in the current DSH tool contract. Whole-file computation in `danger-full-access` should use `node:fs/promises.readFile` or streams and becomes `volatile`.
193
- - Relative Node filesystem entry points, including `node:fs/promises` helpers and globbing, resolve from the recorded session cwd. Absolute paths and explicit filesystem options remain unchanged; sessions without a recorded cwd use the worker's native cwd and are classified as volatile when the access is ambient.
194
- - A recorded `process.cwd` and the `process.exit`/`abort`/`kill`/`chdir` lifecycle guards are immutable, non-configurable realm properties. Lifecycle calls throw `Error` with code `ERR_PTC_PROCESS_CONTROL`; assignment cannot replace these surfaces. Plugin-private `AsyncLocalStorage` receivers have immutable captured `getStore`, `enterWith`, and `run` own methods so user prototype changes cannot alter control state. Separately, during bootstrap only, PTC Plus synchronously intercepts the private Node REPL `AsyncLocalStorage.run` call, protects that one platform receiver, and restores the prototype in `finally` before user source or microtasks can execute.
221
+ - Relative Node filesystem entry points, including `node:fs/promises` helpers and globbing, resolve from the cell's current directory: the recorded cell execution cwd at entry, updated for the remainder of the cell after a confirmed `tools.working_directory` result. Absolute paths and explicit filesystem options remain unchanged; sessions without a recorded cwd use the worker's native cwd and are classified as volatile when the access is ambient.
222
+ - The callable `process.cwd` reports the cell's current directory, including a confirmed in-cell directory change; it and the `process.exit`/`abort`/`kill`/`chdir` lifecycle guards are immutable, non-configurable realm properties. Lifecycle calls throw `Error` with code `ERR_PTC_PROCESS_CONTROL`; assignment cannot replace these surfaces. Plugin-private `AsyncLocalStorage` receivers have immutable captured `getStore`, `enterWith`, and `run` own methods so user prototype changes cannot alter control state. Separately, during bootstrap only, PTC Plus synchronously intercepts the private Node REPL `AsyncLocalStorage.run` call, protects that one platform receiver, and restores the prototype in `finally` before user source or microtasks can execute.
195
223
 
196
224
  `internal/worker-realm-surfaces.js` is the tracked exception registry and write boundary for worker globals, process properties and native prototypes. Every write is classified as a stable native divergence, temporary compiler name, per-cell program binding, user declaration or restoration. A stable write must cite a registry row with the same classification; it cannot borrow a temporary or language-only row. The cwd-projected `node:fs`, `node:fs/promises`, `node:path`, and `node:child_process` callable family is a separate stable surface from `process.cwd`; its verifier compares dynamically enumerated callable descriptors and retained callable properties with a plain Node worker. Private `AsyncLocalStorage` receiver methods are likewise a separate stable surface from the temporary prototype bootstrap. Stable rows name their semantic owner, native or transport reference and executable verifier; a structured source check rejects supported direct `defineProperty`, assignment and deletion forms that bypass the boundary. Module-language behavior remains owned by the compiler/executor contract even when its `require` installation uses the same boundary.
197
225
  - The durable import allowlist is `node:assert`, `node:buffer`, `node:querystring`, `node:string_decoder`, `node:stream`, `node:url`, `node:util`, and `node:zlib`. Other Node imports remain usable but make the cell volatile.
198
226
  - Direct `node:worker_threads` and `node:cluster` references through static import, dynamic import, or unshadowed `require` are rejected during preflight, before any cell statement executes. Calls to `process.exit`, `process.abort`, `process.kill`, and `process.chdir` are rejected through direct `process`, `require`, and dynamic or static `node:process` imports.
199
227
  - Cold recovery replays journals from the session log; there are no compressed checkpoints or worker-LRU eviction.
200
228
  - DSH services or plugin APIs not exposed as a native tool or owner-provided program binding are not made callable through name-based reflection.
229
+
230
+ ## 值传输失败
231
+
232
+ [PTC Value V1](value-wire.md) 区分 live 值、canonical IPC 与模型展示。输出失败 `PTC-O001` 报告不支持的类型/shape 或预算超限及值路径:类型失败需显式选取支持的数据,预算失败需缩小 graph。普通输出编码失败保留 live binding,不重复执行 cell。程序参数编码失败不派发调用;已完成调用的结果编码失败明确报告可能已有外部效果,不自动重试或重置。诊断不为识别类型执行 getter、toJSON 或用户方法。
@@ -1,6 +1,6 @@
1
1
  # 语义义务与编译验证
2
2
 
3
- [`semantic-obligations.json`](../semantic-obligations.json) 是插件自有语义边界的 tracked owner graph,[ADR 0031](adr/0031-close-semantic-obligations-by-owner.md) 定义其闭合范围。`npm run semantic:check` 要求 `internal/`、`src/`、`index.js`、`client.js` 与 journal migration entry 中的每个受管实现文件恰好归属一个义务,并核对 contract、可执行 evidence、依赖图、journal 连续代际以及 language/module 导出代际。报告分别统计 `preserved`、`intentional-difference`、`bounded-external` 与 `unknown`;只有 `unknown: 0` 才表示声明范围内闭合,不表示对全部 Node 或 DSH 行为的等价证明。
3
+ [`semantic-obligations.json`](../semantic-obligations.json) 是插件自有语义边界的 tracked owner graph,[ADR 0031](adr/0031-close-semantic-obligations-by-owner.md) 定义其闭合范围。`npm run semantic:check` 要求 `internal/`、`src/`、`index.js`、`client.cjs` 与 journal migration entry 中的每个受管实现文件恰好归属一个义务,并核对 contract、可执行 evidence、依赖图、journal 连续代际以及 language/module 导出代际。报告分别统计 `preserved`、`intentional-difference`、`bounded-external` 与 `unknown`;只有 `unknown: 0` 才表示声明范围内闭合,不表示对全部 Node 或 DSH 行为的等价证明。
4
4
 
5
5
  每项义务必须记录 owner、实现边界、源 contract、可观察量、入口、生命周期、代际、平台边界、消费者、oracle 与 evidence。新增文件会直接使 source inventory 失败;现有 owner 内新增转换时,维护者还必须判断它是否改变当前义务、依赖或 oracle。能够从中央注册点机械闭合的边界继续使用更强检查,例如 realm mutation 的分类写入入口、journal schema 和 language/module generation set。该图不能替代具体反例、覆盖率或独立 review lane。
6
6
 
@@ -10,7 +10,7 @@
10
10
  | --- | --- | --- |
11
11
  | 保留的 JavaScript 语义 | 固定版本的 Test262 原文与官方 assertion harness;先在新的 Node Script realm 执行,再在新的 stateful/protected cell 执行 | `test/semantic-test262.test.js` |
12
12
  | PTC 方言 | 声明来源 × 后续操作的明确契约;检查旧闭包、保存的原值、完整 declarator 发布、失败后的状态与真实效果 | `test/semantic-dialect.test.js` |
13
- | 编译器边界 | 协议操作、参数环境或动态错误 × root/function/eval/module 入口;同一源码先在原生 Node 执行,再比较 PTC 的值与显式源码效果 | `test/semantic-boundaries.test.js` |
13
+ | 编译器边界 | 协议操作、参数环境或动态错误 × root/function/eval/module 入口;同一源码先在原生 Node 执行,再比较 PTC 的值与显式源码效果 | `test/semantic-boundaries.test.js`、`test/semantic-boundary-{storage,promises,reflection}.test.js` |
14
14
 
15
15
  Test262 子集位于 `test/fixtures/test262/`。`manifest.json` 记录上游仓库、精确 revision、每份原始文件的 SHA-256、语义主题和适用策略。测试验证源码及 harness 的校验值,遵守 strict/noStrict 运行要求;未知 flags、缺少 includes 和未适配的 negative 测试直接使测试配置失败。harness canary 验证错误断言确实会在两个执行路径中失败。
16
16
 
@@ -20,6 +20,10 @@ Test262 子集位于 `test/fixtures/test262/`。`manifest.json` 记录上游仓
20
20
 
21
21
  扩充子集时,从 manifest 的 revision 检出 Test262,原样复制所选用例、依赖的 harness 和 LICENSE,更新校验值及语义主题;升级 revision 时核对全部已选文件。普通测试始终读取仓库内固定输入。优先补齐未覆盖的语义规则与入口组合,而非堆积同一反例的拼写变体。
22
22
 
23
+ 这些测试验证用户可修改的 JavaScript 对象与插件内部编译操作之间的语义关系。例如替换 `Map.prototype.get` 后,用户对该方法的调用仍应观察替换结果,编译器私有存储则应继续完成编译。描述此类用例时,写明被修改的对象、执行入口与预期观察;已有源码、API、诊断和确实涉及安全边界的问题保留准确名称。
24
+
25
+ 编译器边界按参数/namespace/错误分类、存储协议、Promise 协议和反射协议分文件执行,共享 `test/semantic-boundary-fixture.js` 的源码构造与原生 oracle。协议集合互斥且完整,全部 8 个协议 × 6 种操作 × 4 个入口仍逐一比较;每次比较继续创建独立的原生 Worker 和 PTC runtime,不共享被修改的 intrinsic 或执行状态。常规 backend 与 `test:semantics` 使用同一文件并发上限。
26
+
23
27
  矩阵是有限笛卡尔积,失败名称会给出协议、操作和入口,可用 Node 的 `--test-name-pattern` 单独复现。原生比较不执行 lowering 产物来生成预期值。涉及对象身份或副作用顺序的规则还需要直接契约断言;相同 JSON 不能证明任意对象等价。扩大生成范围时保留稳定输入和可独立复现的最小案例,禁止无记录的随机种子或无限生成。
24
28
 
25
29
  当前边界矩阵包括参数默认值闭包与函数体 eval 的组合、六种描述符继承字段与 namespace 反射,以及替换错误构造器后的 eval / Function 失败。装饰器测试用维护中的 TypeScript 标准装饰器 lowering 作独立对照,验证继承属性不成为私有控制状态,同时保留公开 context/access 对象的原型和显式属性读取。资源专项测试把私有栈、函数绑定和 Promise 协议同时替换,并检查 getter/disposer 的原生 caller、receiver、GetMethod 校验顺序、异步间隔和异常身份;原生 Node 24 与强制降级路径比较,Node 22 执行降级路径。真实模块直接持有资源声明,源码重建另经共享语言 lowerer 验证。连续控制台测试跨 cell 保留协议修改,再验证后续计算与恢复,沿用原有资源限额。
@@ -31,3 +35,11 @@ Test262 子集位于 `test/fixtures/test262/`。`manifest.json` 记录上游仓
31
35
  完整确定性检查与有效的独立审查 lane 聚合是提交门槛,不代表发布稳定性证明。发布前仍需补齐 Node 22/24 下连续会话、反复创建与释放 worker、覆盖插桩和资源压力组合的稳定性验证。进程级失败必须保留原始退出码、signal 与 stderr;仅有测试文件级 `test failed` 无法区分运行时缺陷、引擎退出或外部终止。
32
36
 
33
37
  Windows Node 24/26 的 worker teardown native 崩溃已由插件自有 helper 进程边界限制在可回收子进程内(见 [ADR 0027](adr/0027-run-the-session-kernel-in-a-killable-helper-process.md));`npm run check` 现在执行一次确定性运行,不再根据 TAP 文件级 abort 自动重试。发布前仍须在受支持 Node 版本上保留原始退出码、signal 与 stderr,并覆盖连续创建/释放 helper、覆盖插桩和资源压力组合。文件级失败仍按实际 owner 修复,不得用重试掩盖。
38
+
39
+ ## Test descriptions
40
+
41
+ 测试名称优先写对象、操作与可观察结果:属性 getter 抛错、`ownKeys` 返回越界索引、前一轮输出失败后下一轮仍可执行,都比笼统描述对象的意图更便于选择和诊断。局部变量按测试角色命名,参数化名称保留能区分失败分支的参数。
42
+
43
+ 术语按实际契约判断。Cordis `inject`、字符串转义、作用域外保留的引用、完整性校验和真实权限边界保留准确名称;不使用关键词替换表去改写 API、产品诊断、历史代际源码、Test262、快照或编译输入。改名时检查 `--test-name-pattern`、fixture 导出选择器和其他按名称选例的消费者;行为不变的措辞修改不删断言、不缩小测试发现范围。
44
+
45
+ 默认只报告本次选择、结果和失败位置。需要排查时读取对应失败的完整证据,避免反复搬运整个测试目录、已通过用例名称与历史日志。措辞明确和减少重复上下文不构成对供应商接纳率的证明。
@@ -626,7 +626,7 @@ C2/C3/C4 要求分别描述:
626
626
 
627
627
  ### 8.4 journal 代际与旧代码
628
628
 
629
- 当前封闭 schema 的版本常量与字段集由 [session-journal-schema.js](../internal/session-journal-schema.js) 拥有,JOURNAL_VERSION 为 10;schema 包含 languageSemantics、精确的 moduleTransform、bindingPolicy、rewritePolicy、moduleSemantics(含 `importExpressionBoundary`)、userBindingsFingerprint、userBindingsReusePolicy、userBindingsShadowPolicy 与 userBindingNames 等字段。字段校验、journal 创建与旧代际迁移由 [session-journal.js](../internal/session-journal.js) 拥有,事件关联与折叠恢复由 [session-journal-recovery.js](../internal/session-journal-recovery.js) 拥有。旧 ADR 描述其决策发生时的版本,不能用历史版本叙述替代当前 schema 事实。
629
+ 当前封闭 schema 的版本常量与字段集由 [session-journal-schema.js](../internal/session-journal-schema.js) 拥有,JOURNAL_VERSION 为 11;schema 以 executionCwd 记录每个 cell 的绝对执行目录,v1–v10 仍采用其历史 header/worker 基准([ADR 0041](adr/0041-record-cell-execution-directories.md));schema 包含 languageSemantics、精确的 moduleTransform、bindingPolicy、rewritePolicy、moduleSemantics(含 `importExpressionBoundary`)、userBindingsFingerprint、userBindingsReusePolicy、userBindingsShadowPolicy 与 userBindingNames 等字段。字段校验、journal 创建与旧代际迁移由 [session-journal.js](../internal/session-journal.js) 拥有,事件关联与折叠恢复由 [session-journal-recovery.js](../internal/session-journal-recovery.js) 拥有。旧 ADR 描述其决策发生时的版本,不能用历史版本叙述替代当前 schema 事实。
630
630
 
631
631
  新代际必须区分:所有作用域可写规则、裸声明、声明 pattern 提交、import/default 来源关联、特殊命名空间、动态 grammar goal、独立单元、name 级用户绑定覆盖和实际操作证据。只重解释原有两个布尔值无法表达这些变化。
632
632
 
@@ -723,7 +723,7 @@ G1/G2 给出单元性质,G3 使动态新单元继续满足它,G4 使状态
723
723
 
724
724
  C1–C4 的效用指标包括:完成任务所需调用数、因内部表示而改名/包块/查库存的次数、恢复后错误引用状态的次数、错误值与重复外部效果次数。报错减少但结果变错不算改善,源码更少但隐藏状态更多也不算改善。
725
725
 
726
- [大型依赖验收](../test/stateful-large-dependency.test.js)在默认 worker 内存和执行预算下加载 TypeScript、实际调用编译 API,并验证重复加载身份与后续 cell 的状态连续性,覆盖更新、保护及两种历史设置。资源验收使用未启用覆盖率采集的独立 Node 进程,测量正常执行条件;编译器语义由常规覆盖率测试验证。不以提高预算或跳过依赖编译替代通过。
726
+ [大型依赖验收](../test/stateful-large-dependency.test.js)在默认 worker 内存和执行预算下加载 TypeScript、实际调用编译 API,并验证重复加载身份与后续 cell 的状态连续性,覆盖更新、保护及两种历史设置。资源验收使用未启用覆盖率采集的独立 Node 进程,测量正常执行条件;编译器语义由日常确定性测试验证,覆盖率只在发布新版本前采集。不以提高预算或跳过依赖编译替代通过。
727
727
 
728
728
  针对当前 proposal 的文档验证检查链接、源码事实、推导索引、相互引用与历史语义界限。后续实现按仓库 ledger 流程登记 correction、owner、dependents 与判别式验证;本提案不自动解决已记录的运行时 finding。
729
729
 
@@ -18,7 +18,7 @@ To revise a saved binding, use `/binding edit <id> <requirement>`. Its storage `
18
18
 
19
19
  ## Draft panel
20
20
 
21
- A new draft opens above the composer. Click the title bar or use Enter/Space to collapse and expand it. Long content scrolls inside the panel.
21
+ A new draft floats above the composer. Click the title bar or use Enter/Space to collapse and expand it without moving the conversation or composer. Long content scrolls inside the panel. When space above the composer is limited, the preview shows only its header and enlarge action. If even the header cannot fit, the composer menu and historical request keep the draft entry; manual draft entries always open the large dialog. Choose **Enlarge binding draft** for a large review dialog with independently scrolling content and save/discard actions kept at the bottom. The header keeps resize and close controls spaced apart. Escape, the backdrop, or **Shrink binding draft** returns to preview without saving or discarding; if preview cannot fit, focus returns to the composer entry. The separate close button hides the draft panel, which can be reopened from the sparkle menu.
22
22
 
23
23
  - **Save as disabled**: keep the entry in the global list without loading it.
24
24
  - **Save and enable**: save it and allow subsequent calls to load it.
@@ -27,7 +27,7 @@ A new draft opens above the composer. Click the title bar or use Enter/Space to
27
27
 
28
28
  The sparkle button shows a delayed PTC Plus tooltip identifying it as the global bindings and settings entry; a pending draft changes it to the draft state. The tooltip stays hidden while the menu, management dialog, or settings dialog is open. The button shows a badge for pending drafts. Open its menu by hovering, clicking, or using the keyboard, then select the draft to show it again. Each session retains one current candidate. A confirmed save or discard closes the panel; failures leave the draft available for retry.
29
29
 
30
- The sparkle menu is available before the first message and opens once the pointer dwells on the entry; incidental pointer movement across the composer leaves it closed. A hovered menu closes as soon as the pointer leaves it; clicking keeps it open until you click again, click elsewhere, or press Escape. Global bindings show their names, purposes, and enabled states using status text and color. Click an entry to toggle it for all sessions. The catalog refreshes in the background, and the entries stay usable while it does; writes are serialized, so an entry stays usable during an in-flight write and a duplicate toggle is dropped rather than queued, and you reload after a conflict or failure before trying again. **Manage global bindings** opens the full workbench. **Write a new binding** and **Revise a binding** appear when the authoring command is available; the revision step lists existing entries and prefills `/binding edit <id> `. The reusable REPL binding list shows how many later cells reused each binding, with the total in the section title; the count comes from static references in each later cell's compiled source, and a redeclaration counts as neither a reuse nor a reset of the accumulated count.
30
+ The sparkle menu is available before the first message and opens once the pointer dwells on the entry; incidental pointer movement across the composer leaves it closed. A hovered menu closes as soon as the pointer leaves it; clicking keeps it open until you click again, click elsewhere, or press Escape. Global bindings are grouped by enabled state with counts. Enabled entries appear first; each menu opening starts with the disabled group collapsed. Click the group or press Enter/Space to expand it. Entries retain their names, purposes, and status text. Only the catalog scrolls; authoring, revision, management, and settings actions stay at the bottom, as does Back in the revision step. Click an entry to toggle it for all sessions. The catalog refreshes in the background, and the entries stay usable while it does; writes are serialized, so an entry stays usable during an in-flight write and a duplicate toggle is dropped rather than queued, and you reload after a conflict or failure before trying again. After a toggle, focus follows the regrouped entry, or returns to the disabled group button if that group hides the entry; focus outside the menu is left alone. Recovery scrolls only the binding list to reveal the target, leaving the footer and conversation in place. **Manage global bindings** opens the full workbench. **Write a new binding** and **Revise a binding** appear when the authoring command is available; the revision step lists existing entries and prefills `/binding edit <id> `. The reusable REPL binding list shows how many later cells reused each binding, with the total in the section title; the count comes from static references in each later cell's compiled source, and a redeclaration counts as neither a reuse nor a reset of the accumulated count.
31
31
 
32
32
  The original binding request retains its requirement, status, and accepted source in history. Historical inspection does not restore permission to save that draft. When another edit changes the catalog, reload its current state before deciding whether to save.
33
33
 
@@ -18,16 +18,16 @@
18
18
 
19
19
  ## 草稿面板
20
20
 
21
- 新草稿自动在输入框上方展开。点击标题栏或使用 Enter/Space 折叠、展开;长内容可在面板内滚动。
21
+ 新草稿自动悬浮在输入框上方。点击标题栏或使用 Enter/Space 折叠、展开,不挤动对话和输入框;长内容可在面板内滚动;输入框上方空间不足时只显示标题栏,仍可放大查看;连标题也放不下时保留星光菜单和历史请求的草稿入口,手动草稿入口始终直接打开大窗口。点击 **放大查看绑定草稿** 打开大尺寸审阅窗口,正文独立滚动,底部始终保留保存与丢弃按钮。标题栏的尺寸切换与关闭按钮之间留有间距。按 Escape、点击遮罩或 **缩小显示绑定草稿** 返回预览;预览没有可用空间时焦点回到星光入口,不保存或丢弃草稿。独立关闭按钮隐藏草稿面板,可从星光菜单重新打开。
22
22
 
23
23
  - **保存为停用**:保存到全局列表,暂不加载。
24
24
  - **保存并启用**:保存并允许后续调用加载。
25
25
  - **丢弃草稿**:放弃这份未保存候选。
26
26
  - **关闭面板**:只隐藏面板,不保存或丢弃。
27
27
 
28
- 输入框星光按钮显示待处理草稿的角标。悬停、点击或键盘打开菜单后,选择草稿即可重新显示。每个会话保留一份当前候选。保存或丢弃确认成功后面板关闭;失败时保留草稿供重试。
28
+ 输入框星光按钮显示待处理草稿的角标。悬停、点击或键盘打开菜单后,选择草稿即可在大窗口中重新审阅。每个会话保留一份当前候选。保存或丢弃确认成功后面板关闭;失败时保留草稿供重试。
29
29
 
30
- 星光按钮的 PTC Plus 提示延迟显示,说明它是全局绑定与设置入口;有待处理草稿时改为提示草稿状态。菜单、管理窗口或设置窗口打开时隐藏提示,避免遮挡。星光菜单在首条消息发出前即可使用,鼠标停留一下才展开,扫过输入区不会弹出。悬停打开后鼠标移开菜单即自动关闭;点击可让菜单保持常开,再点一次、点击别处或按 Escape 关闭。全局绑定按名称和用途列出,状态文字与颜色样式表示启用状态;点击条目切换启停,配置对所有会话生效。目录在后台刷新,刷新期间沿用上一次的列表并可以继续操作;切换写入逐条串行化,写入进行中条目保持可用,重复请求被直接丢弃;发生冲突或失败时可重新加载后再操作。“管理全局绑定”打开完整工作台;编写命令可用时显示“编写新绑定”和“修改绑定”,“修改绑定”第二步从已有条目中选择后预填 `/binding edit <id> `。REPL 可复用绑定列表会显示每项被后续 cell 复用的次数,并在区块标题显示总复用次数;次数按后续 cell 编译后源码中的静态引用统计,重定义或重声明本身不算一次复用,也不会把已累计的次数清零。
30
+ 星光按钮的 PTC Plus 提示延迟显示,说明它是全局绑定与设置入口;有待处理草稿时改为提示草稿状态。菜单、管理窗口或设置窗口打开时隐藏提示,避免遮挡。星光菜单在首条消息发出前即可使用,鼠标停留一下才展开,扫过输入区不会弹出。悬停打开后鼠标移开菜单即自动关闭;点击可让菜单保持常开,再点一次、点击别处或按 Escape 关闭。全局绑定按启用、停用分组并显示数量,已启用条目优先展示,停用组每次打开菜单时默认折叠,可点击或用 Enter/Space 展开;条目保留名称、用途与状态文字。只有绑定列表滚动,底部编写、修改、管理与设置操作固定可见,“修改绑定”第二步的“返回”也固定在底部;点击条目切换启停,配置对所有会话生效。目录在后台刷新,刷新期间沿用上一次的列表并可以继续操作;切换写入逐条串行化,写入进行中条目保持可用,重复请求被直接丢弃;发生冲突或失败时可重新加载后再操作。启停后条目进入对应分组;焦点仍在菜单中时跟随该条目,若条目进入折叠的停用组则回到组按钮,不抢走菜单外的焦点。焦点恢复仅滚动绑定列表来显示目标,不移动底栏或对话。“管理全局绑定”打开完整工作台;编写命令可用时显示“编写新绑定”和“修改绑定”,“修改绑定”第二步从已有条目中选择后预填 `/binding edit <id> `。“刷新会话能力”沿用相同输入框保护,预填 `/capabilities refresh` 后由用户发送,不直接执行;输入框已有草稿时保留原文。菜单从已启用分组开始,不显示全局生效范围说明;停用组使用与面板一致的浅色折叠行,主菜单与“修改绑定”列表共用状态小胶囊,启用显示绿色、停用显示灰色,编写与四个工具操作采用双列按钮,图标两侧留出对称空间以保持文字居中,柔和底色替代描边。REPL 可复用绑定列表会显示每项被后续 cell 复用的次数,并在区块标题显示总复用次数;次数按后续 cell 编译后源码中的静态引用统计,重定义或重声明本身不算一次复用,也不会把已累计的次数清零。
31
31
 
32
32
  历史中的“绑定编写”请求保留需求、状态和接受时的源码。它供查看当时内容,不重新获得保存资格。目录发生并发修改时,重新加载最新状态后再决定是否保存。
33
33
 
@@ -52,10 +52,20 @@ DSH 的公共执行缝/tool output 只接受 JSON-safe structured value。为保
52
52
  - renderer 只是模型展示,不参与 hydrate;需要继续计算时应保留 live REPL binding;
53
53
  - journal 保存 canonical graph envelope,不保存 renderer 反解析结果,也不把 decoded rich value 交给外层 `JSON.stringify`。
54
54
 
55
- unsupported value 或预算超限使用 `PTC-O001`,帮助文本只要求返回受支持的 PTC value 或缩小结果;`undefined` 属于受支持值,不要求模型用 `null` 替换。
55
+ unsupported value、shape 与预算超限使用 `PTC-O001` 并给出路径与对应帮助:预算超限要求缩小 graph;类型或 descriptor 不支持要求显式选取所需 data。已完成计算不会自动重试或清空 worker,可在后续 cell 使用 retained binding。Date 可显式选取 ISO 文本或 timestamp,Map/Set 可显式选取 entries/values;这些是调用方选择的数据投影,不是 codec 自动转换。诊断不调用 getter、toJSON、用户方法或额外的 Proxy reflection;未知原型不猜测 class name。`undefined` 属于受支持值,不要求模型用 `null` 替换。
56
56
 
57
57
  cell program binding 的参数和结果经过同一 graph IPC,因此 owner-provided binding 可以接收和返回
58
58
  完整 `PTCValueV1` 支持域,包括 `undefined`、special number、BigInt、hole、shared identity 与 cycle。
59
59
  跨 worker 后得到的是 hydrate 的值图,不是同一个 live object;function、class instance、Promise、
60
60
  accessor 和其他不在支持域内的资源会在 dispatch 前或返回 cell 前被拒绝。journal 保存相同的 canonical
61
61
  envelope,cold replay 以 recorded value 重建结果而不重新调用 owner binding。
62
+
63
+ ## 子计算与 native 边界
64
+
65
+ 插件自有隔离 `code.run` 从已结算的 canonical completion hydrate 子值,保留支持域内的类型、hole、cycle 与 shared identity,不合并父子 binding。无 return 时省略 `result`,显式 `return undefined` 时保留该属性。递归子计算使用同一边界;内部 program completion 校验 graph 与传输预算,不生成无用的模型展示,因此可在父程序中读取无需展开的稀疏数组。真实 native `run_code` member 的委托仍返回其 owner-defined canonical result;legacy upstream 分支保留原契约。历史 recorded-value 字符串原样读取,不反解析或重新执行子 cell。决策与平台 serializer 评估见 [ADR 0034](adr/0034-keep-program-values-separate-from-output-projections.md)。
66
+
67
+ 以上 graph IPC 能力不扩展 native `tools.*` 的 JSON 输入/输出契约。真实调用仍由 DSH 按 live schema 与 lossless JSON 验证;BigInt 在插件内部可传输,但不能据此作为 native JSON 参数。直接 `return {big: 2n}` 无需 `JSON.stringify`;显式 `JSON.stringify` 对 BigInt 的拒绝和 `2n + 1` 的混合算术错误保持原生语义,不自动丢精度转换。
68
+
69
+ 模型检查结果时可直接返回所需数据或类型观察。`JSON.stringify` 是显式 JSON 格式选择:它省略对象中的 `undefined` 和函数,将 `NaN`、正负 Infinity 写成 `null`,将 `-0` 写成 `0`;这些文本不再证明原值的类型或区别。函数和资源留在 live binding 中使用,输出明确选取其可传输观察,不自动过滤不支持的成员。
70
+
71
+ program binding 参数编码失败发生在 dispatch 前;已完成 binding 的返回值编码失败明确报告调用已完成及可能已有外部效果,不能仅为取得结果重复调用。完成结果的拒绝保持 worker live;参数/结果错误仍使用该程序入口的错误路径。纯数据对象不在 V1 支持域时仍可在 live binding 内计算;live 可用性不证明跨边界传输或 cold recovery 能力。
@@ -2,19 +2,23 @@
2
2
 
3
3
  ## Purpose
4
4
 
5
- `npm run coverage:focus` provides a bounded diagnostic loop for executable
6
- changes. It checks selected gate-owned sources with the smallest test set that
7
- can distinguish a correction before the repository-wide release gate runs.
5
+ `npm run coverage:focus` provides a bounded diagnostic loop for coverage
6
+ failures while preparing a new version for release. It checks selected
7
+ gate-owned sources with the smallest test set that can distinguish a correction
8
+ before the full release coverage gate runs again.
8
9
 
9
- The focused command does not replace `npm run verify` or `npm run check` and
10
- does not write a verified-tree proof. [Deterministic verification](verification.md)
11
- owns command syntax, thresholds, generated evidence, and the final gate.
10
+ Coverage is not part of ordinary development, review, commit preparation,
11
+ `npm run verify`, or `npm run check`; coverage-specific suites and instrumented cases are also excluded from those daily entries. The focused command does not replace the
12
+ full release coverage gate and does not write a verified-tree proof.
13
+ [Release coverage](release-coverage.md) owns coverage command syntax, thresholds,
14
+ generated evidence, and the final gates; [ADR 0035](adr/0035-run-coverage-only-before-a-new-release.md)
15
+ owns coverage scheduling.
12
16
 
13
17
  ## Contract
14
18
 
15
19
  - Every selected source and test must exist inside the checkout.
16
20
  - Selected sources must belong to the full coverage gate, and selected tests
17
- must be `test/*.test.js` files.
21
+ must be `.test.js` files under `test/`.
18
22
  - Selected but unexecuted sources remain in the report as uncovered.
19
23
  - The report applies the full gate's 100% line/function and 95% branch
20
24
  thresholds.
@@ -24,17 +28,50 @@ owns command syntax, thresholds, generated evidence, and the final gate.
24
28
  - Node test options may follow a standalone `--` after the focused source and
25
29
  test selections.
26
30
 
31
+ Compiler instrumentation belongs to the test runner, not the compiler service.
32
+ The runner prepares bytecode without coverage, then preloads
33
+ `scripts/instrument-compiler-coverage.mjs` before the compiler captures Node's
34
+ `Script` constructor. Only the exact compiler bundle bypasses cached bytecode
35
+ consumption during that run; cache export uses the prepared, uninstrumented
36
+ bytes. The real-worker testing entry installs the same seam before importing
37
+ the production worker, removes its private entry locator and bytecode-path
38
+ environment variable, restores the ordinary worker's `process.argv[1]` through
39
+ the worker realm restoration boundary, and then runs the unchanged worker. Production compilation
40
+ does not read `NODE_V8_COVERAGE` or `DSH_PTC_COMPILER_BYTECODE` and never opens a
41
+ file selected by those variables.
42
+
43
+ The testing `Script` seam preserves the compiler's option prototype and property
44
+ descriptors while disabling only `cachedData`. Ordinary scripts keep their
45
+ original options. Descriptor conversion uses the shared compiler descriptor
46
+ owner; the seam captures its required primordials before user execution so
47
+ caller prototype and static-method mutations cannot reach private compilation.
48
+ Prepared cache export copies typed-array internal data through a captured native
49
+ constructor, without invoking public length getters on its private snapshot.
50
+ The shared compiler platform also uses captured native byte operations for
51
+ encoding and decoding, so first-use TypeScript lowering cannot invoke a caller's
52
+ replacement typed-array length getter in either ordinary or covered execution.
53
+ Covered and ordinary workers use the same absolute entry
54
+ normalization for URL objects, file-URL strings, and filenames; the testing
55
+ preload does not independently reinterpret a caller's entry.
56
+
27
57
  ## Workflow
28
58
 
29
- Use focused coverage after the nearest behavioral test passes or after a full
30
- gate identifies a narrow coverage deficit. Select every changed source whose
31
- threshold matters and the tests that exercise its distinct paths. A passing
32
- focused run establishes only that selected relation.
59
+ During ordinary development, use the selection-required behavioral entries in
60
+ [verification](verification.md) without coverage. Executable changes alone do not
61
+ trigger a complete gate; [ADR 0036](adr/0036-separate-focused-development-from-delivery-verification.md)
62
+ owns the development versus delivery boundary.
63
+ During release preparation, use focused coverage after the full release coverage
64
+ gate identifies a narrow deficit. Select every changed source whose threshold
65
+ matters and the tests that exercise its distinct paths. A passing focused run
66
+ establishes only that selected relation; rerun the full coverage gate before
67
+ packing and staging.
33
68
 
34
- Run one final `npm run verify` while the local review ledger has unresolved
35
- findings. Once every finding is terminal, run `npm run check` on a stable tree
36
- to produce the proof consumed by the commit hook. Do not run `verify`
37
- immediately before `check` on the same tree because `check` already invokes it.
69
+ When complete validation is requested for delivery, timing or an identified
70
+ cross-suite risk, run one final command on the stable candidate: `npm run verify`
71
+ with unresolved findings, otherwise `npm run check -- --full`. Terminal findings alone do
72
+ not trigger another gate. A still-matching proof is reused for delivery; focused
73
+ results never replace it. Do not run `verify` immediately before `check` on the
74
+ same tree because the full check already invokes it.
38
75
 
39
76
  Temporary concurrency overrides change scheduling only. Use one only when
40
77
  current evidence identifies scheduling contention, and do not carry it into a