dsh-ptc-plus 0.4.10 → 0.5.1

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 (125) hide show
  1. package/README.en.md +65 -127
  2. package/README.md +65 -127
  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 +42702 -0
  10. package/cordis.patch.yml +1 -0
  11. package/docs/README.md +6 -2
  12. package/docs/adr/0005-temporary-rejected-cell-edit-transport.md +31 -198
  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 +4 -4
  17. package/docs/adr/0019-plugin-settings-and-kill-switch.md +1 -1
  18. package/docs/adr/0020-optional-cordis-tools-in-ptc-mode.md +1 -1
  19. package/docs/adr/0022-stage-npm-releases-with-oidc.md +4 -2
  20. package/docs/adr/0023-global-user-bindings.md +2 -0
  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 +25 -23
  23. package/docs/adr/0031-close-semantic-obligations-by-owner.md +1 -1
  24. package/docs/adr/0034-keep-program-values-separate-from-output-projections.md +29 -0
  25. package/docs/adr/0035-run-coverage-only-before-a-new-release.md +27 -0
  26. package/docs/adr/0036-separate-focused-development-from-delivery-verification.md +29 -0
  27. package/docs/adr/0037-keep-tool-hover-previews-passive.md +52 -0
  28. package/docs/adr/0038-freeze-session-capability-plans.md +71 -0
  29. package/docs/adr/0039-verify-documentation-without-runtime-suites.md +29 -0
  30. package/docs/adr/0040-separate-capability-configurations-from-session-observations.md +39 -0
  31. package/docs/adr/0041-record-cell-execution-directories.md +65 -0
  32. package/docs/adr/0042-persist-provider-availability-and-handback.md +41 -0
  33. package/docs/adr/0043-compose-capability-and-context-policies.md +37 -0
  34. package/docs/adr/0044-coexist-with-the-official-persistent-repl.md +35 -0
  35. package/docs/adr/README.md +8 -0
  36. package/docs/architecture.md +23 -25
  37. package/docs/capability-planning-components.md +93 -0
  38. package/docs/capability-projection.md +7 -0
  39. package/docs/client-ui.md +70 -23
  40. package/docs/client-visual-contract.md +26 -9
  41. package/docs/context-management.md +22 -0
  42. package/docs/context-optimization-plan.md +353 -0
  43. package/docs/context-public-interface-coverage.md +25 -0
  44. package/docs/durability-design.md +20 -15
  45. package/docs/evaluation.md +41 -6
  46. package/docs/evaluations/command-goat-deepseek-v4.1-flash-20261006.md +126 -0
  47. package/docs/evaluations/command-goat-deepseek-v4.1-flash.md +281 -0
  48. package/docs/installation.md +33 -10
  49. package/docs/program-data-plane.md +5 -3
  50. package/docs/publishing.md +7 -7
  51. package/docs/release-coverage.md +73 -0
  52. package/docs/release-notes.md +1 -1
  53. package/docs/review-procedure.md +56 -0
  54. package/docs/runtime-reference.md +53 -16
  55. package/docs/semantic-validation.md +14 -2
  56. package/docs/stateful-binding-updates-proposal.md +2 -2
  57. package/docs/user-bindings.md +1 -1
  58. package/docs/value-wire.md +11 -1
  59. package/docs/verification-optimization-work.md +26 -15
  60. package/docs/verification.md +30 -88
  61. package/index.js +146 -20
  62. package/internal/binding-toggle-receipt.js +24 -0
  63. package/internal/capability-command-receipt.js +31 -0
  64. package/internal/capability-environment.js +1253 -0
  65. package/internal/capability-plan.js +285 -0
  66. package/internal/capability-policy.js +96 -0
  67. package/internal/capability-statistics-store.js +180 -0
  68. package/internal/capability-statistics.js +214 -0
  69. package/internal/config-spec.js +89 -10
  70. package/internal/direct-surface-owner.js +27 -29
  71. package/internal/dynamic-environment-runtime.js +9 -9
  72. package/internal/edit-transport-owner.js +195 -140
  73. package/internal/execution-provider-owner.js +40 -12
  74. package/internal/execution-seam-compat.js +26 -8
  75. package/internal/kernel-worker.js +104 -32
  76. package/internal/native-root-dynamic.js +12 -13
  77. package/internal/official-repl-priority.js +51 -0
  78. package/internal/program-bindings.js +190 -0
  79. package/internal/recovery-tips.js +3 -2
  80. package/internal/rejected-cell-editor.js +8 -8
  81. package/internal/repl-observation-interest.js +11 -3
  82. package/internal/rpc-contract.js +1 -0
  83. package/internal/runtime-bridge-owner.js +275 -34
  84. package/internal/runtime-config.js +58 -0
  85. package/internal/runtime-contexts.js +74 -5
  86. package/internal/runtime-intrinsics.js +1 -0
  87. package/internal/runtime-messages.js +41 -0
  88. package/internal/sdk-projection.js +10 -82
  89. package/internal/session-cell-executor.js +42 -19
  90. package/internal/session-events.js +34 -0
  91. package/internal/session-journal-recovery.js +234 -11
  92. package/internal/session-journal-schema.js +6 -3
  93. package/internal/session-journal.js +31 -2
  94. package/internal/session-log-view.js +1 -1
  95. package/internal/session-runtime.js +119 -15
  96. package/internal/settings-compat.js +12 -5
  97. package/internal/stateful-module-compiler.js +3 -2
  98. package/internal/stateful-module-runtime.js +7 -3
  99. package/internal/stateful-root-runtime.js +9 -4
  100. package/internal/user-binding-authoring.js +2 -7
  101. package/internal/user-bindings-owner.js +19 -2
  102. package/internal/validated-parse-repair.js +1 -1
  103. package/internal/value-wire.js +68 -21
  104. package/internal/worker-cwd-virtualization.js +20 -18
  105. package/internal/worker-realm-surfaces.js +3 -3
  106. package/package.json +49 -30
  107. package/src/client-activity.js +3 -2
  108. package/src/client-authoring-view.js +67 -30
  109. package/src/client-binding-review.js +2 -1
  110. package/src/client-binding-toggle.js +18 -0
  111. package/src/client-capabilities-view.js +1555 -0
  112. package/src/client-capability-sort.js +29 -0
  113. package/src/client-copy.js +923 -8
  114. package/src/client-feature-gates.js +3 -0
  115. package/src/client-indicator-view.js +4 -6
  116. package/src/client-primitives.js +33 -2
  117. package/src/client-repl-view.js +20 -13
  118. package/src/client-settings-view.js +411 -41
  119. package/src/client-styles.js +112 -15
  120. package/src/client-tool-hover.js +185 -0
  121. package/src/client-tool-view.js +45 -9
  122. package/src/client-transport.js +44 -9
  123. package/src/client-workbench.js +6 -7
  124. package/src/client.js +76 -22
  125. package/client.js +0 -32479
@@ -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. Every rejection names the captured cell (`run_code call <seq>` plus a bounded first line), so a drifted target stays identifiable, and a guard mismatch also states that only the most recent settled cell remains editable and that corrected source should be re-submitted with `run_code` when the intended cell is gone. The settled log line reports the same target identity. 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.
@@ -75,6 +101,7 @@ Missing-description diagnostics append a complete DSH user message to `additiona
75
101
  autoDescribeRunCode: true
76
102
  bindingUpdates: 'stateful'
77
103
  durableReplay: true
104
+ officialReplPriority: false
78
105
  tipsEnabled: true
79
106
  cordisToolsEnabled: false
80
107
  userBindingsEnabled: true
@@ -93,9 +120,11 @@ Missing-description diagnostics append a complete DSH user message to `additiona
93
120
 
94
121
  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
122
 
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 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)) — 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.
123
+ `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.
124
+
125
+ `officialReplPriority` defaults to `false` and is evaluated against the live provider capability rather than a release number: a provider reporting `programFormat: 'repl'` is an official persistent in-memory REPL. With the setting enabled and that provider live, this host attachment installs no session runtime, so `run_code` and its descriptors — `programFormat`, `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 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)`.
97
126
 
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.
127
+ `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
128
 
100
129
  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
130
 
@@ -131,19 +160,21 @@ Every completed cell records the exact source-derived active snapshot in private
131
160
 
132
161
  `durableReplay: false` starts new kernels without recorded REPL state while preserving live bindings in the current process. It does not delete session logs.
133
162
 
163
+ Submission admission belongs to the exact DSH tool execution. Reentry within that execution shares its admission; a later root execution gets a fresh admission and session observation even when a background callback inherits the same session's asynchronous context or reuses a call ID. Only a proved derived edit may inherit its composite source and settlement evidence. Disposing a child agent/session leaves the parent's live bindings intact. Disposing the parent cancels its pending preparation; the next admitted call can recover from the verified journal without reusing that cancelled admission.
164
+
134
165
  With `durableReplay: true`, recovery claims only bindings backed by both verified journal ancestry and exact provenance available to the model that produced the current call. DSH's append-only event log proves reconstructability; its ordered model-visible surface proves awareness. Before every subsequent cell in a structured host session, the runtime revalidates each existing live call against that exact surface even when `replaceGeneration` is unchanged. Raw events shadowed from the surface and UI-only `dshPtcPlusBindings` metadata do not make a binding model-knowable. A result-only replacement may retain a cell when the assistant call containing its source remains visible. If compaction shadows that call, the live worker and cold recovery contract the affected state unless an explicitly selected bounded structured projection exposes the exact bindings in model context. Such a projection is not injected by default merely to retain hidden state. Natural-language summaries are not parsed as state evidence.
135
166
 
136
167
  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
168
 
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.
169
+ 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
170
 
140
171
  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
172
 
142
173
  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
174
 
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.
175
+ 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
176
 
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.
177
+ 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
178
 
148
179
  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
180
 
@@ -161,7 +192,7 @@ Rewrites are recorded as `meta.dshPtcPlusRewrites` on the tool result (parallel
161
192
 
162
193
  | Code | Meaning | State effect |
163
194
  | --- | --- | --- |
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 |
195
+ | `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
196
  | `PTC-C002` | Preflight rejected a kernel-control import | Not executed; REPL unchanged |
166
197
  | `PTC-N001` | Top-level binding conflict | Not executed; REPL unchanged |
167
198
  | `PTC-O001` | Unsupported or over-budget output | Cell executed; earlier mutations may exist |
@@ -170,19 +201,21 @@ Rewrites are recorded as `meta.dshPtcPlusRewrites` on the tool result (parallel
170
201
  | `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
202
  | `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
203
 
204
+ 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.
205
+
173
206
  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
207
 
175
208
  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
209
 
177
210
  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
211
 
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.
212
+ 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
213
 
181
214
  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
215
 
183
216
  ## Named State
184
217
 
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.
218
+ `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
219
 
187
220
  ## Limits
188
221
 
@@ -190,11 +223,15 @@ Inside a cell, omitting the JavaScript argument of a native `tools` member is ac
190
223
 
191
224
  - 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
225
  - `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.
226
+ - 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.
227
+ - 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
228
 
196
229
  `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
230
  - 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
231
  - 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
232
  - Cold recovery replays journals from the session log; there are no compressed checkpoints or worker-LRU eviction.
200
233
  - DSH services or plugin APIs not exposed as a native tool or owner-provided program binding are not made callable through name-based reflection.
234
+
235
+ ## 值传输失败
236
+
237
+ [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
 
@@ -27,7 +27,7 @@
27
27
 
28
28
  输入框星光按钮显示待处理草稿的角标。悬停、点击或键盘打开菜单后,选择草稿即可在大窗口中重新审阅。每个会话保留一份当前候选。保存或丢弃确认成功后面板关闭;失败时保留草稿供重试。
29
29
 
30
- 星光按钮的 PTC Plus 提示延迟显示,说明它是全局绑定与设置入口;有待处理草稿时改为提示草稿状态。菜单、管理窗口或设置窗口打开时隐藏提示,避免遮挡。星光菜单在首条消息发出前即可使用,鼠标停留一下才展开,扫过输入区不会弹出。悬停打开后鼠标移开菜单即自动关闭;点击可让菜单保持常开,再点一次、点击别处或按 Escape 关闭。全局绑定按启用、停用分组并显示数量,已启用条目优先展示,停用组每次打开菜单时默认折叠,可点击或用 Enter/Space 展开;条目保留名称、用途与状态文字。只有绑定列表滚动,底部编写、修改、管理与设置操作固定可见,“修改绑定”第二步的“返回”也固定在底部;点击条目切换启停,配置对所有会话生效。目录在后台刷新,刷新期间沿用上一次的列表并可以继续操作;切换写入逐条串行化,写入进行中条目保持可用,重复请求被直接丢弃;发生冲突或失败时可重新加载后再操作。启停后条目进入对应分组;焦点仍在菜单中时跟随该条目,若条目进入折叠的停用组则回到组按钮,不抢走菜单外的焦点。焦点恢复仅滚动绑定列表来显示目标,不移动底栏或对话。“管理全局绑定”打开完整工作台;编写命令可用时显示“编写新绑定”和“修改绑定”,“修改绑定”第二步从已有条目中选择后预填 `/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.
@@ -52,15 +56,22 @@ preload does not independently reinterpret a caller's entry.
52
56
 
53
57
  ## Workflow
54
58
 
55
- Use focused coverage after the nearest behavioral test passes or after a full
56
- gate identifies a narrow coverage deficit. Select every changed source whose
57
- threshold matters and the tests that exercise its distinct paths. A passing
58
- 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.
59
68
 
60
- Run one final `npm run verify` while the local review ledger has unresolved
61
- findings. Once every finding is terminal, run `npm run check` on a stable tree
62
- to produce the proof consumed by the commit hook. Do not run `verify`
63
- 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.
64
75
 
65
76
  Temporary concurrency overrides change scheduling only. Use one only when
66
77
  current evidence identifies scheduling contention, and do not carry it into a