dsh-ptc-plus 0.3.2 → 0.4.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.
- package/README.en.md +65 -78
- package/README.md +65 -78
- package/assets/ptc-plus-bindings-en.png +0 -0
- package/assets/ptc-plus-bindings-zh.png +0 -0
- package/assets/ptc-plus-repair-en.png +0 -0
- package/assets/ptc-plus-repair-zh.png +0 -0
- package/assets/ptc-plus-repl-workspace-en.png +0 -0
- package/assets/ptc-plus-repl-workspace-zh.png +0 -0
- package/assets/ptc-plus-settings-en.png +0 -0
- package/assets/ptc-plus-settings-zh.png +0 -0
- package/client.js +30596 -742
- package/compiler-amaro.cjs +5 -0
- package/compiler-amaro.cjs.map +6 -0
- package/compiler-asset-124f80c1bba92ff5fe79cfec6e8ad518f476de4a42514cae3919538887f510e8.txt +1 -0
- package/compiler-assets.json +3 -0
- package/compiler-core.cjs +554 -0
- package/compiler-core.cjs.map +6 -0
- package/compiler-platform.cjs +2 -0
- package/compiler-platform.cjs.map +6 -0
- package/compiler-typescript.cjs +388 -0
- package/compiler-typescript.cjs.map +6 -0
- package/docs/README.md +6 -0
- package/docs/adr/0004-declare-program-bindings-at-the-host.md +1 -1
- package/docs/adr/0006-rewrite-module-syntax-with-an-ast.md +5 -3
- package/docs/adr/0007-separate-worker-transport-from-session-semantics.md +1 -1
- package/docs/adr/0009-bound-expensive-acceptance-default.md +2 -0
- package/docs/adr/0010-session-log-derived-recovery-tips.md +59 -5
- package/docs/adr/0011-isolate-the-local-recovery-tip-provider.md +1 -1
- package/docs/adr/0012-preserve-mixed-destructuring-initialization.md +3 -1
- package/docs/adr/0013-isolate-repl-redeclaration-convenience.md +3 -1
- package/docs/adr/0014-persist-cell-rewrite-policy.md +6 -2
- package/docs/adr/0015-preserve-source-positions-through-rewrites.md +1 -1
- package/docs/adr/0016-archive-resolved-review-findings.md +1 -1
- package/docs/adr/0017-track-the-latest-dsh-public-surface.md +49 -0
- package/docs/adr/0018-use-versioned-fixture-for-ab-benchmark.md +3 -3
- package/docs/adr/0019-plugin-settings-and-kill-switch.md +5 -3
- package/docs/adr/0020-optional-cordis-tools-in-ptc-mode.md +2 -2
- package/docs/adr/0021-separate-host-bootstrap-from-session-runtime.md +12 -0
- package/docs/adr/0023-global-user-bindings.md +104 -0
- package/docs/adr/0024-repl-console-observation.md +33 -0
- package/docs/adr/0025-use-versioned-logical-binding-identities.md +119 -0
- package/docs/adr/0026-persist-the-delivery-verdict-against-the-verified-candidate.md +21 -0
- package/docs/adr/0027-run-the-session-kernel-in-a-killable-helper-process.md +37 -0
- package/docs/adr/0028-attach-to-the-host-ptc-execution-seam.md +103 -0
- package/docs/adr/0029-keep-plugin-unavailability-out-of-the-host-agent-lifecycle.md +27 -0
- package/docs/adr/0030-serve-both-typert-codec-generations-from-one-codec.md +27 -0
- package/docs/architecture.md +73 -21
- package/docs/binding-review-placement-design.md +200 -0
- package/docs/capability-projection.md +1 -1
- package/docs/client-ui.md +95 -19
- package/docs/durability-design.md +25 -10
- package/docs/evaluation.md +78 -6
- package/docs/installation.md +41 -6
- package/docs/publishing.md +5 -3
- package/docs/runtime-reference.md +72 -25
- package/docs/semantic-validation.md +29 -0
- package/docs/stateful-binding-updates-proposal.md +755 -0
- package/docs/user-bindings.en.md +64 -0
- package/docs/user-bindings.md +64 -0
- package/docs/value-wire.md +3 -3
- package/docs/verification.md +57 -0
- package/index.js +369 -92
- package/internal/ast-traversal.js +5 -2
- package/internal/binding-descriptors.js +1 -0
- package/internal/binding-pattern-traversal.js +25 -0
- package/internal/binding-pattern.js +26 -29
- package/internal/binding-source-analysis.js +391 -0
- package/internal/binding-update-policy.js +66 -0
- package/internal/bounded-worker-round.js +56 -0
- package/internal/callable-definition-environment.js +42 -0
- package/internal/callable-source-catalog.js +129 -0
- package/internal/callable-source-encoding.js +47 -0
- package/internal/callable-source-facts.js +459 -0
- package/internal/callable-source-format.js +2 -0
- package/internal/callable-source-lowering.js +123 -0
- package/internal/cell-analysis-contract.js +25 -0
- package/internal/cell-analysis.js +240 -290
- package/internal/cell-completion.js +15 -0
- package/internal/cell-error.js +7 -0
- package/internal/cell-parser.js +66 -0
- package/internal/cell-rewriter.js +3 -677
- package/internal/commonjs-export-evidence.js +63 -0
- package/internal/commonjs-source-evidence.js +72 -0
- package/internal/compiler-amaro.cjs +2 -0
- package/internal/compiler-compression.js +12 -0
- package/internal/compiler-data.js +58 -0
- package/internal/compiler-descriptors.js +54 -0
- package/internal/compiler-dynamic-cache.js +48 -0
- package/internal/compiler-entry.js +35 -0
- package/internal/compiler-generated-names.js +17 -0
- package/internal/compiler-intrinsics.js +84 -0
- package/internal/compiler-module-links.js +34 -0
- package/internal/compiler-operations.js +61 -0
- package/internal/compiler-platform-factory.js +84 -0
- package/internal/compiler-platform.js +136 -0
- package/internal/compiler-record-roles.js +53 -0
- package/internal/compiler-region-output.js +259 -0
- package/internal/compiler-resource-lowering.js +103 -0
- package/internal/compiler-scope-facts.js +115 -0
- package/internal/compiler-service.js +109 -0
- package/internal/compiler-source-cache.js +32 -0
- package/internal/compiler-source-pieces.js +93 -0
- package/internal/compiler-source-regions.js +132 -0
- package/internal/compiler-storage-source.js +54 -0
- package/internal/compiler-text.js +15 -0
- package/internal/compiler-typescript.cjs +2 -0
- package/internal/config-spec.js +83 -27
- package/internal/cordis-tools-owner.js +130 -21
- package/internal/diagnostic.js +27 -1
- package/internal/direct-surface-owner.js +76 -23
- package/internal/dynamic-binding-evidence.js +16 -0
- package/internal/dynamic-environment-compiler.js +779 -0
- package/internal/dynamic-environment-integration.js +87 -0
- package/internal/dynamic-environment-runtime.js +362 -0
- package/internal/dynamic-native-calls.js +150 -0
- package/internal/dynamic-native-runtime.js +248 -0
- package/internal/dynamic-scope-analysis.js +90 -0
- package/internal/edit-transport-owner.js +27 -2
- package/internal/execution-seam-compat.js +193 -0
- package/internal/failure-reporting.js +118 -18
- package/internal/host-rpc.js +66 -0
- package/internal/isolated-worker.js +548 -0
- package/internal/kernel-child.js +139 -0
- package/internal/kernel-worker.js +904 -120
- package/internal/language-semantics.js +14 -0
- package/internal/legacy-binding-catalog.js +48 -0
- package/internal/legacy-cell-analysis.js +600 -0
- package/internal/legacy-cell-parser.js +50 -0
- package/internal/legacy-cell-rewriter.js +631 -0
- package/internal/legacy-repl-convenience.js +291 -0
- package/internal/managed-module-operations.js +170 -0
- package/internal/module-compilation.js +321 -0
- package/internal/module-runtime-platform.js +19 -0
- package/internal/module-transform-contract.js +12 -0
- package/internal/native-await-declarations.js +68 -0
- package/internal/native-root-compilation.js +54 -0
- package/internal/native-root-dynamic.js +67 -0
- package/internal/recovery-tips.js +27 -15
- package/internal/rejected-cell-editor.js +13 -8
- package/internal/repl-convenience.js +2 -289
- package/internal/repl-memory-projection.js +81 -12
- package/internal/repl-observation-interest.js +70 -0
- package/internal/repl-rewrite-contract.js +6 -0
- package/internal/repl-scope-normalizer.js +2091 -0
- package/internal/repl-value-observer.js +114 -0
- package/internal/rpc-contract.js +52 -0
- package/internal/runtime-bridge-owner.js +172 -28
- package/internal/runtime-config.js +48 -52
- package/internal/runtime-contexts.js +82 -10
- package/internal/runtime-messages.js +111 -0
- package/internal/session-cell-executor.js +401 -87
- package/internal/session-journal-recovery.js +684 -0
- package/internal/session-journal-schema.js +106 -0
- package/internal/session-journal.js +184 -654
- package/internal/session-log-view.js +42 -9
- package/internal/session-runtime.js +256 -95
- package/internal/session-state.js +247 -71
- package/internal/source-position-map.js +211 -71
- package/internal/stateful-module-compiler.js +154 -0
- package/internal/stateful-module-runtime.js +303 -0
- package/internal/stateful-root-compiler.js +598 -0
- package/internal/stateful-root-runtime.js +340 -0
- package/internal/typert-codec-compat.js +28 -0
- package/internal/typescript-transform.js +29 -0
- package/internal/user-binding-authoring.js +70 -0
- package/internal/user-binding-console-worker.js +184 -0
- package/internal/user-binding-console.js +148 -0
- package/internal/user-binding-draft-projection.js +335 -0
- package/internal/user-binding-model-context.js +31 -0
- package/internal/user-binding-runner.js +56 -0
- package/internal/user-bindings-owner.js +1065 -0
- package/internal/user-bindings-store.js +293 -0
- package/internal/user-bindings.js +353 -0
- package/internal/value-wire-schema.js +28 -0
- package/internal/value-wire.js +29 -20
- package/internal/worker-client.js +57 -67
- package/internal/worker-environment.js +45 -0
- package/internal/worker-output-relay.js +29 -0
- package/internal/worker-shutdown.js +14 -0
- package/package.json +75 -7
- package/src/client-activity.js +88 -53
- package/src/client-authoring-view.js +580 -0
- package/src/client-binding-review.js +230 -0
- package/src/client-bindings-data.js +29 -0
- package/src/client-catalog.js +127 -0
- package/src/client-code-editor.js +84 -0
- package/src/client-console.js +112 -0
- package/src/client-copy.js +370 -0
- package/src/client-feature-gates.js +62 -0
- package/src/client-host-compat.js +150 -0
- package/src/client-indicator-view.js +267 -0
- package/src/client-repl-view.js +292 -0
- package/src/client-rpc.js +20 -0
- package/src/client-settings-view.js +221 -0
- package/src/client-styles.js +106 -0
- package/src/client-tool-view.js +108 -0
- package/src/client-transport.js +159 -0
- package/src/client-workbench.js +521 -0
- package/src/client.js +233 -615
package/docs/README.md
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
## Getting Started
|
|
4
4
|
|
|
5
5
|
- [Installation](installation.md): npm, Git, source, tarball, development snapshot, and Desktop installation.
|
|
6
|
+
- [Global binding guide](user-bindings.en.md) ([中文](user-bindings.md)): author, review, save, configure, and test reusable helpers.
|
|
6
7
|
- [Runtime Reference](runtime-reference.md): cell behavior, capability discovery, configuration, diagnostics, and limits.
|
|
7
8
|
- [Evaluation](evaluation.md): paired ordinary-task protocol, metrics, configuration, and limitations.
|
|
8
9
|
|
|
@@ -13,9 +14,14 @@
|
|
|
13
14
|
- [Program Data Plane](program-data-plane.md): canonical values and result completeness.
|
|
14
15
|
- [Durable / Volatile Recovery](durability-design.md): replay model and external-input boundaries.
|
|
15
16
|
- [PTC Value Graph V1](value-wire.md): supported JavaScript value encoding.
|
|
17
|
+
- [Global User Bindings](adr/0023-global-user-bindings.md): persistent helper ownership, model projection, runtime activation, recovery, and Agent-assisted authoring.
|
|
18
|
+
- [Binding Review Placement](binding-review-placement-design.md): the implemented full draft panel above the current composer, using the published input dock and one review controller.
|
|
19
|
+
- [Logical Binding Identities](adr/0025-use-versioned-logical-binding-identities.md): stateful declarations, scope, candidate publication and language generations.
|
|
16
20
|
- [Architecture Decisions](adr/): stable design constraints and their consequences.
|
|
17
21
|
|
|
18
22
|
## Maintenance
|
|
19
23
|
|
|
24
|
+
- [Deterministic Verification](verification.md): complete checks, backend test concurrency, coverage, and focused diagnostics.
|
|
25
|
+
- [Semantic Validation](semantic-validation.md): pinned Test262 cases, dialect contracts, native differential matrices and their limits.
|
|
20
26
|
- [Publishing](publishing.md): release checks, package contents, permissions, and platform validation.
|
|
21
27
|
- [Client UI](client-ui.md): current UI boundary and reevaluation criteria.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Declare Program Bindings At The Owner
|
|
2
2
|
|
|
3
|
-
PTC Plus does not create a private cross-plugin registry or reflective invocation bus. The
|
|
3
|
+
PTC Plus does not create a private cross-plugin registry or reflective invocation bus. The public execution-seam request surface ([ADR 0028](0028-attach-to-the-host-ptc-execution-seam.md)) has no registry for discovering non-tool program bindings.
|
|
4
4
|
|
|
5
5
|
If DSH later provides one, capability owners should publish explicit typed contracts, semantic metadata, source references, and binding factories. DSH should own discovery, scope, authority, leasing, dispatch, and settlement. Explicit registration, generated manifests, decorators, or scanning are assembly choices; none replaces those contracts. PTC Plus would consume only bindings already present in the live request.
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
# Rewrite Module Syntax With An AST
|
|
2
2
|
|
|
3
|
+
The AST and native module-resolution decision remains in force. The alias storage, readonly writes and collision rules below describe the frozen `legacy-v1` compiler; [ADR 0025](0025-use-versioned-logical-binding-identities.md) supersedes those rules for new cells and unifies plugin-owned module compilation. `internal/legacy-cell-rewriter.js`, `internal/legacy-cell-parser.js` and `internal/legacy-cell-analysis.js` preserve that historical contract.
|
|
4
|
+
|
|
3
5
|
## Problem
|
|
4
6
|
|
|
5
7
|
PTC Plus evaluates each cell as an async function body, where static `import` and `export` declarations are syntactically invalid. The adapter must accept TypeScript type syntax, preserve cell-relative source positions and line counts, classify the rewritten program for replay durability, record every automatic rewrite, and reject malformed or unrecognized module syntax without partially deleting or transforming it. Token-by-token text scanning duplicated parser responsibilities and could accept a recognized prefix while leaving an invalid suffix or erase malformed type-only declarations.
|
|
6
8
|
|
|
7
9
|
## Decision
|
|
8
10
|
|
|
9
|
-
[`internal/cell-rewriter.js`](../../internal/cell-rewriter.js) owns module-syntax adaptation. `@babel/parser` parses the original cell with its TypeScript plugin under script semantics while explicitly allowing top-level module declarations, `return`, and `await`; recognizing a module declaration therefore does not impose module strict mode on the surrounding async-function body. Before any edit or module preload record is produced, `@babel/traverse` builds the original Program scope. Its declaration and hoisting rules reject same-scope collisions between value imports and lexical, `var`, function, or other import bindings while retaining block shadowing and the separate TypeScript type namespace. The same scope validates local exports and drives imported-reference rewriting, supplemented by top-level TypeScript declaration names because Babel intentionally excludes the type namespace from runtime scope. The rewriter derives every accepted import, export, type-only declaration, specifier, source value, and edit range from that AST. One batch edit assembler validates non-overlapping ranges, produces generated source, and composes source mappings without rebuilding either artifact per edit. [`internal/cell-
|
|
11
|
+
[`internal/legacy-cell-rewriter.js`](../../internal/legacy-cell-rewriter.js) owns historical module-syntax adaptation. `@babel/parser` parses the original cell with its TypeScript plugin under script semantics while explicitly allowing top-level module declarations, `return`, and `await`; recognizing a module declaration therefore does not impose module strict mode on the surrounding async-function body. Before any edit or module preload record is produced, `@babel/traverse` builds the original Program scope. Its declaration and hoisting rules reject same-scope collisions between value imports and lexical, `var`, function, or other import bindings while retaining block shadowing and the separate TypeScript type namespace. The same scope validates local exports and drives imported-reference rewriting, supplemented by top-level TypeScript declaration names because Babel intentionally excludes the type namespace from runtime scope. The rewriter derives every accepted import, export, type-only declaration, specifier, source value, and edit range from that AST. One batch edit assembler validates non-overlapping ranges, produces generated source, and composes source mappings without rebuilding either artifact per edit. [`internal/legacy-cell-parser.js`](../../internal/legacy-cell-parser.js) owns executable parsing of the prepared cell: it wraps the rewritten cell as an async function body, parses it with Acorn, and relocates every returned AST range to original-cell coordinates. Already-valid JavaScript proceeds unchanged; only a cell that Acorn cannot parse is passed through Node's `stripTypeScriptTypes` and parsed again. [`internal/legacy-cell-analysis.js`](../../internal/legacy-cell-analysis.js) consumes that single parse for binding and durability analysis.
|
|
10
12
|
|
|
11
13
|
Each static import or remote re-export creates an ordered module preload record. A value-bearing record carries its source, import attributes, original position, generated temporary-global identifier, and the default or named exports required by its AST specifiers. The dedicated worker uses Node's synchronous module resolve hook to give REPL imports and static-link adapters one parent at the session cwd, falling back to the worker process cwd when the session has no recorded cwd. Node's ESM resolver therefore owns relative URLs, bare packages, conditional `exports`, URL schemes, import conditions, and platform path conversion; plugin and target-module dependency imports retain their natural parents. Each ephemeral data-URL adapter expresses the required members as static re-exports, so Node completes export linkage before evaluating the target module, then returns the namespace for a value-bearing preload. The worker resolves records before compiling the cell and exposes each namespace under its temporary identifier. One generated lexical prologue after the original directive prologue and before every executable cell statement captures each temporary identifier into a distinct persistent namespace identifier in source order; import declarations are erased at their original ranges, and the temporary globals are removed when the cell settles. Both identities are allocated outside current source identifiers, persistent REPL bindings, reserved program bindings, and every live private namespace. The prologue references the generated host identifier directly, so a lexical `globalThis` binding has ordinary JavaScript semantics and cannot redirect capture. A binding catalog stores only the persistent namespace identity and maps public import aliases to it and the export name; scope-aware rewriting routes unshadowed reads through the namespace, keeps bare, optional, and tagged calls detached from the namespace receiver with the language's comma-reference form, and lowers writes to a deterministic `TypeError`. Private namespace names remain reserved after a public alias is redeclared, so closures from earlier cells cannot be redirected by a later import. The catalog is rebuilt during journal replay. In loose REPL mode an explicit later declaration replaces the alias for future cells, while closures compiled before that declaration retain their namespace read. Destructuring, loop, nested, and delete writes that cannot preserve native evaluation semantics are rejected before execution. Direct `eval` and `WithStatement` are rejected on the original Program while value import aliases are active because generated namespace reads cannot reproduce their dynamic lexical resolution; this validation precedes module preload. Indirect or locally shadowed eval, non-strict `with` without active aliases, and cells containing only type imports retain ordinary JavaScript semantics. Side-effect, default, namespace, named, default-plus-named, and default-plus-namespace forms remain supported. Export modifiers are removed while declarations remain; default exports map the fixed public name `__default` through the same alias lowering to a generated persistent private slot. Later default exports update that slot at their source position independently of variable-redeclaration policy, and the binding catalog adopts the alias definition only after the worker reports the generated post-update commit signal. This keeps `__default` live and read-only while preventing an early return or failed class evaluation from publishing an update that did not execute. Anonymous default function and class lowering emits an explicit statement terminator, while default expressions retain their parsed continuation; remote re-exports become preload-only side-effect modules; local export lists are removed; and declaration-level or specifier-level type-only syntax is erased.
|
|
12
14
|
|
|
13
|
-
The rewriter normalizes Babel syntax and local-export validation failures as original-cell positions before they cross the module boundary. Executable
|
|
15
|
+
The rewriter normalizes Babel syntax and local-export validation failures as original-cell positions before they cross the module boundary. Executable parsing normalizes AST ranges and parse failures to original-cell coordinates inside that parse owner, so `PTC-C001` renders `ModuleRewriteError.cellPosition` without applying any wrapper offset; a failure raised while parsing the module-rewrite output is mapped back through that rewrite's source map before preparation returns. [`internal/legacy-cell-analysis.js`](../../internal/legacy-cell-analysis.js) then applies return, redeclaration, collision, and durability analysis to the successfully rewritten program. Return control-flow lowering addresses its per-cell worker-global signal through the top-level `this` receiver, which bypasses both lexical `globalThis` shadowing and `with` object-environment resolution; worker startup validates that this receiver is the evaluator's global context, and settlement removes the signal property. Lowered returns emit an explicit statement terminator so a return in a `switch` clause remains valid after replacement. Rewrite provenance remains parallel to the closed journal schema under `meta.dshPtcPlusRewrites` and does not alter replay equality. A successful rewrite remains private audit metadata; only a failed rewrite or missing valid journal may project its description as a bounded recovery context.
|
|
14
16
|
|
|
15
17
|
## Alternatives considered
|
|
16
18
|
|
|
@@ -42,4 +44,4 @@ The rewriter normalizes Babel syntax and local-export validation failures as ori
|
|
|
42
44
|
|
|
43
45
|
## Consequences
|
|
44
46
|
|
|
45
|
-
Each accepted transformation corresponds to a complete TypeScript AST node, and every automatic type erasure produces provenance without recovering module names from source text. Static modules resolve from the session project in source order before cell compilation; their aliases are initialized before body execution regardless of textual declaration position or an earlier return. A resolution, linkage, or evaluation failure leaves REPL declarations and aliases uncommitted, although a successfully completed earlier preload may already have produced effects. A preload with a missing requested export does not evaluate its target module. Imported reads add one namespace property access; bare, optional, and tagged calls use an indirect reference so the namespace cannot become `this` and nullish optional calls still short-circuit. Malformed module or type syntax and unsupported imported writes fail before execution. The production dependency set includes `@babel/parser
|
|
47
|
+
Each accepted transformation corresponds to a complete TypeScript AST node, and every automatic type erasure produces provenance without recovering module names from source text. Static modules resolve from the session project in source order before cell compilation; their aliases are initialized before body execution regardless of textual declaration position or an earlier return. A resolution, linkage, or evaluation failure leaves REPL declarations and aliases uncommitted, although a successfully completed earlier preload may already have produced effects. A preload with a missing requested export does not evaluate its target module. Imported reads add one namespace property access; bare, optional, and tagged calls use an indirect reference so the namespace cannot become `this` and nullish optional calls still short-circuit. Malformed module or type syntax and unsupported imported writes fail before execution. The production dependency set includes `@babel/parser`, `@babel/traverse`, and `acorn`; Acorn remains the executable-JavaScript and scope-analysis authority downstream. TypeScript lowering of global binding modules is a separate mechanism with its own owner, [`internal/typescript-transform.js`](../../internal/typescript-transform.js), which pins its transform generation and does not parse or rewrite cells ([ADR 0023](0023-global-user-bindings.md)). Module resolution uses Node's `registerHooks` primitive available at the engine floor. Node's `stripTypeScriptTypes` is invoked only when the rewritten cell is not already valid JavaScript and remains experimental at the current engine floor, so the compatibility suite must be rerun when the supported Node version changes.
|
|
@@ -8,7 +8,7 @@ The session runtime coordinates two different lifecycles: transport ownership fo
|
|
|
8
8
|
|
|
9
9
|
[`internal/worker-client.js`](../../internal/worker-client.js) exclusively owns worker creation, the readiness handshake, the private port, bounded stderr capture, reset, concurrent termination tracking, scratch allocation, and scratch cleanup. It reports private-channel messages and terminal failures through callbacks. [`internal/session-runtime.js`](../../internal/session-runtime.js) owns the active cell and decides how a reported message or failure settles the journal, durability state, replay transaction, or binding call. Messages reach the kernel only from the client's current worker, while each active semantic transaction retains its worker identity for lease and replay checks.
|
|
10
10
|
|
|
11
|
-
Cross-process policy that must agree on both sides has one source. [`internal/module-policy.js`](../../internal/module-policy.js) defines durable imports, forbidden kernel-control imports, and ambient globals for both static analysis and the worker runtime. [`internal/failure-reporting.js`](../../internal/failure-reporting.js) defines hostile-error normalization, active-cell stack extraction, bounded diagnostic logs, and repeat-failure tracking for the host and worker. Session-log recovery belongs to [`internal/session-journal.js`](../../internal/session-journal.js), which owns
|
|
11
|
+
Cross-process policy that must agree on both sides has one source. [`internal/module-policy.js`](../../internal/module-policy.js) defines durable imports, forbidden kernel-control imports, and ambient globals for both static analysis and the worker runtime. [`internal/failure-reporting.js`](../../internal/failure-reporting.js) defines hostile-error normalization, active-cell stack extraction, bounded diagnostic logs, and repeat-failure tracking for the host and worker. Session-log recovery belongs to [`internal/session-journal-recovery.js`](../../internal/session-journal-recovery.js), which owns event association and branch folding; the closed field sets and generation constants belong to [`internal/session-journal-schema.js`](../../internal/session-journal-schema.js), and journal validation, migration, and creation belong to [`internal/session-journal.js`](../../internal/session-journal.js). Live durable nodes, current-call exclusion, no-op confirmations, recovery boundaries, and cold nodes all use persisted `tool/call.seq` identity. During live dispatch, the journal owner uses `callId` only to resolve the unique unpaired top-level call, then passes its sequence into semantic state. Sessionless direct runtime calls do not fabricate a persisted identity. Journal v3 stores confirmed no-ops as sequences; v2 journals with empty confirmations migrate without ambiguity, while a v2 call-id confirmation forms an unknown boundary. A failed durable replay records one log-only recovery boundary in the current settled `tool/result` metadata under `meta.dshPtcPlusRecoveryBoundaries`; its payload identifies the failed call event and its parent frontier without inventing a DSH event type. Every boundary is normalized as it enters recovery before its event sequence participates in ordering. Malformed boundary or association data is rejected as evidence for old state, but it does not turn historical plugin metadata into an availability gate for the current valid call. A completed record enters branch folding at its `tool/result` event position because that event confirms durability. Folding leaves immutable call/result events intact, removes unproved nodes and dependent descendants, and recomputes checkpoints from the remaining records. [`internal/session-runtime.js`](../../internal/session-runtime.js) resets the worker and retries the greatest verified frontier, recursively reaching the empty REPL if every non-empty candidate fails, then executes the current cell against that actual state. The contraction is recorded on the current settled result and reported once so later recovery does not repeatedly encounter the same boundary. The exported migration helper converts old custom boundary events into this metadata before DSH restores a session and never mutates its input.
|
|
12
12
|
|
|
13
13
|
Recovery is conservative about state and best-effort about availability. A post-boundary cell or binding may be retained only when owned evidence mechanically proves that its ancestry or independence does not cross the unknown boundary. The current journal does not contain a complete per-binding dependency graph, so recovery treats a cell as atomic and discards its affected suffix when it cannot prove a finer partition. This can lose bindings, including all bindings in the empty-frontier case, but never claims that an unverified heap or historical effect was restored. DSH policy and failures of the current request remain outside this fallback.
|
|
14
14
|
|
|
@@ -16,6 +16,8 @@ The edit canary covers both a completed cell whose result needs adjustment and a
|
|
|
16
16
|
|
|
17
17
|
Both model-backed runners complete keyless verification and resolved-config validation before model invocation. They then run one complete representative canary sequentially and audit its process result, session log, tool transport, runtime contexts, budgets, and task oracle before scheduling broader scenarios, replicates, or concurrency. A canary failure stops the run without starting the remaining paid work. Deterministic tests remain the authority for AST rewrite variants and the acceptance contract itself. The ordinary-task A/B canary is the stable fixture's fixed, cheap, machine-checkable transport task rather than a full repository test run; see ADR 0018.
|
|
18
18
|
|
|
19
|
+
Resolved tools settings are independently validated by DSH's public configuration schema, in addition to the runner's policy comparison. Workload-specific inspection symbols and operation limits belong to the scenario's `programWork` expectations. These limits use canonical argument evidence and include failed calls; identical arguments never authorize runtime deduplication or prove observation freshness. The fixed typed fixture permits one native read and reuse of that observation. Guarded edits reuse the canonical editor and dispatch-time target projection; explicitly expected guard mismatches require a non-executing result without derived metadata. Deterministic coverage of these contracts does not enlarge the default paid cohort.
|
|
20
|
+
|
|
19
21
|
Machine acceptance and stochastic comparison are separate from blind semantic review. A/B output reports machine pass or failure independently and keeps overall approval pending until the blind packets have been evaluated; producing packets is not evidence that their review is complete.
|
|
20
22
|
|
|
21
23
|
## Alternatives considered
|
|
@@ -2,21 +2,75 @@
|
|
|
2
2
|
|
|
3
3
|
## Problem
|
|
4
4
|
|
|
5
|
-
The persistent REPL contract must stay short enough for every request, while some failures need a model-visible recovery affordance. Repeated binding failures and platform-specific command errors benefit from a precise next action. A real `edit_run_code` call already carries its identity, arguments, and result; restating those facts
|
|
5
|
+
The persistent REPL contract must stay short enough for every request, while some failures need a model-visible recovery affordance. Repeated binding failures and platform-specific command errors benefit from a precise next action. A real `edit_run_code` call already carries its identity, arguments, and result; restating those facts wastes tokens. The former aggregate runtime-context path also repeated unrelated owner contributions whenever any PTC contribution changed. Long-cell failure guidance belongs in the current diagnostic, where pre-execution rejection and possibly effectful failure can be distinguished.
|
|
6
6
|
|
|
7
7
|
## Decision
|
|
8
8
|
|
|
9
|
-
PTC
|
|
9
|
+
PTC-owned dynamic information uses independently sourced, accepted DSH messages.
|
|
10
|
+
Unproved rewrite completion and Cordis recovery form a bounded `ptc-plus`
|
|
11
|
+
`snapshot` with named sections. Configured Global User Binding documentation uses
|
|
12
|
+
DSH's existing `catalog` form, independently of transient recovery state. A recovery tip is a `ptc-plus` `notice` whose
|
|
13
|
+
structured summary is its trigger/ordinal name. A snapshot supersedes only prior
|
|
14
|
+
PTC state snapshots, including PTC sections in historical DSH aggregate snapshots;
|
|
15
|
+
it never supersedes a binding catalog, authoring task, Skill instructions, a tool result, or
|
|
16
|
+
another producer. An empty snapshot explicitly invalidates earlier PTC state.
|
|
10
17
|
|
|
11
|
-
The
|
|
18
|
+
The binding catalog contains one bounded literal configuration document with a
|
|
19
|
+
fixed owner prefix; its reader recognizes that prefix only within a `ptc-plus`
|
|
20
|
+
`catalog` source. Only a later binding catalog replaces it; an explicit empty
|
|
21
|
+
catalog withdraws it. Host runtime-context clearances and PTC recovery snapshots
|
|
22
|
+
do not withdraw catalogs. Suppression prevents new delivery without changing the
|
|
23
|
+
meaning of a retained catalog. This is API documentation, not proof of successful
|
|
24
|
+
initialization, current values, or recoverable session-local state. The historical
|
|
25
|
+
snapshot reader remains intact: an accepted recovery snapshot retires old binding
|
|
26
|
+
sections once, while a catalog supplies the current configuration. No history or
|
|
27
|
+
journal is rewritten. Catalog and recovery changes never resend each other's text.
|
|
12
28
|
|
|
13
|
-
|
|
29
|
+
The binding catalog wrapper names `run_code` as the invocation location and
|
|
30
|
+
limits replacement to the previous global binding API reference. Its body contains
|
|
31
|
+
only entry labels, optional user prompts and selected declarations; checkpoint
|
|
32
|
+
instructions belong to `repl.state` discovery, and authoring instructions belong
|
|
33
|
+
to the `/binding` task. Initialization failures are reported by execution results.
|
|
34
|
+
Readers accept the exact bounded historical wrappers and empty marker as
|
|
35
|
+
well as the emitted form. A wording change does not reinterpret old records or
|
|
36
|
+
require journal migration. Catalog bodies are compared literally, so revised
|
|
37
|
+
documentation can cause one replacement on upgrade and is then deduplicated.
|
|
38
|
+
|
|
39
|
+
The public `systemPrompt.context` registry contains one empty PTC delivery witness.
|
|
40
|
+
DSH omits this contribution when `includeRuntimeContext` is false or a scoped
|
|
41
|
+
runtime-context suppressor applies; the empty text never enters its rendered
|
|
42
|
+
aggregate. The assembly listener captures that witness and the exact request's
|
|
43
|
+
PTC facts, leaving unrelated aggregate content unchanged. `agent/pre-step`
|
|
44
|
+
delegates its waterfall first and adds messages only to an accepted, non-cancelled
|
|
45
|
+
step matching that assembly. It neither calls `inject` after inbox claim nor wakes
|
|
46
|
+
the agent with `steer`, and it cannot override admission or runtime suppression.
|
|
47
|
+
|
|
48
|
+
Delivery is reconstructed from committed messages, never from a proposed step.
|
|
49
|
+
The public ordered Session surface identifies retained current-state snapshots;
|
|
50
|
+
historical aggregate state includes DSH's exact owner-sourced clearance marker.
|
|
51
|
+
An accepted step's pending aggregate replacement can withdraw an old PTC section,
|
|
52
|
+
requiring an independent current declaration in that same step.
|
|
53
|
+
Raw committed history identifies delivered tip ordinals and cooldown distance,
|
|
54
|
+
but cannot make hidden bindings model-visible. Compaction or removal of a state
|
|
55
|
+
snapshot requires a fresh eligible state or an explicit clear. Suppressed steps
|
|
56
|
+
send nothing; the next permitted step reconciles claims. Disabled PTC mode retains
|
|
57
|
+
only the settings surface and a passive presentation cleanup listener, which can
|
|
58
|
+
clear previously delivered claims without mounting runtime tools, reading binding
|
|
59
|
+
storage, or publishing new declarations. Plugin/agent disposal releases pending
|
|
60
|
+
assembly ownership. Resume reconstructs from the same durable source records.
|
|
61
|
+
|
|
62
|
+
PTC Plus keeps the stable REPL guidance limited to invariants, discovery entry points, and environment-neutral boundaries. `internal/session-log-view.js` projects immutable facts for edit targeting, successful-run reset, context distance, normalized Cordis call/inspection counts, canonical historical DSH snapshots, and formed PTC messages. `internal/runtime-contexts.js` renders rewrite feedback only when the rewritten cell lacks a valid journal, Cordis recovery while historical transcript lacks a newer successful live Inspect, and at most one recovery tip. Known failures already carry partial-execution and retry guidance in their result, so they do not generate duplicate rewrite feedback. `internal/runtime-messages.js` owns bounded message forms: snapshot sections total at most 65536 UTF-16 code units and recognize the two historical binding sections for retirement; a catalog body is at most 65536 code units, with the tighter configured-declaration budget still enforced by the binding owner; a notice is at most 8192 code units with a valid trigger/ordinal identity. Malformed records are not delivery evidence. Transparent rewrites remain result metadata. Edit provenance and target lifecycle remain in real call/results and private derived-execution metadata. These messages never change the tool list, tool schemas, or system sections.
|
|
63
|
+
|
|
64
|
+
The default triggers are a repeated binding failure and a failure whose diagnostic or structured cause identifies an executable, shell, or path problem. The first tip is concise. A matching trigger may produce another tip only after `tipCooldownMessages` model-context steps; unresolved matching tips reach the detailed form after `tipEscalationFailures` occurrences. A successful cell resets the unresolved escalation count. Every emitted tip name carries its stable trigger identity and next per-trigger ordinal. Reconstruction merges valid PTC notices and canonical historical sections from DSH's system-prompt owner, counting each delivered identity once across both sources. Unformed tasks and malformed plugin prose are not tip evidence. Visible wording does not determine cooldown or escalation identity; an exhausted safe-integer ordinal yields no further tip.
|
|
65
|
+
|
|
66
|
+
Platform wording names execution-world differences without assuming Windows, WSL, POSIX, a shell, or package-runner availability. Bounded multiline message/stderr facts may supply a missing cause, but generic exit failure alone does not prove an environment problem. Repeated lexical failures point to visible source, scope and initialization; discovery is reserved for worker-owned capability failures. Warning state describes the failed cell conservatively, not the act of emitting a warning. `edit_run_code` remains independently available as a fixed real tool and does not depend on a recovery-tip trigger; a validated result repair only proves syntax/preflight acceptance and retains the target guard and complete-cell execution contract.
|
|
14
67
|
|
|
15
68
|
The Cordis recovery context is not a failure tip and is not controlled by fatigue settings. It narrows the meaning of recorded values after a lifecycle boundary: they remain historical program data but cannot prove current process-local state. It clears only after a newly settled successful `cordis_inspect*` transcript, does not infer whether the original process survived, and never redispatches a historical effect.
|
|
16
69
|
|
|
17
70
|
## Alternatives considered
|
|
18
71
|
|
|
19
72
|
- **Keep all recovery instructions in the stable system prompt.** This makes every request pay for rare failures and makes platform-specific text look universally applicable.
|
|
73
|
+
- **Keep configured APIs inside recovery snapshots.** A short-lived recovery fact would resend unchanged interfaces on both entry and withdrawal. Catalogs already express the required public Host semantics; a new delta protocol or producer registry is unnecessary.
|
|
20
74
|
- **Emit a tip after every matching failure.** This repeats stale advice, consumes context, and can encourage blind retry loops.
|
|
21
75
|
- **Store mutable tip counters only in the kernel.** A worker restart or replay would then change model-visible behavior without a session-log source.
|
|
22
76
|
- **Infer tip identity from rendered prose or one fixed section name.** Wording changes would reset history, unrelated plugin text could create false matches, and an unchanged aggregate context would not persist repeated occurrences.
|
|
@@ -26,4 +80,4 @@ The Cordis recovery context is not a failure tip and is not controlled by fatigu
|
|
|
26
80
|
|
|
27
81
|
## Consequences
|
|
28
82
|
|
|
29
|
-
Normal requests receive only the persistent REPL invariants in stable system text.
|
|
83
|
+
Normal requests receive only the persistent REPL invariants in stable system text. Renderers consume projected facts; accepted-step delivery rechecks committed history and the public surface before proposing bounded messages. A PTC transition appends no unrelated owner text, and another owner's aggregate transition does not resend unchanged PTC state. A new tip ordinal records a separate notice even when compact wording repeats, while repeated historical copies do not advance fatigue state. Tip thresholds are configurable; disabling tips stops future notices without removing `edit_run_code` or any native capability. Historical records require no migration.
|
|
@@ -6,7 +6,7 @@ Recovery tips are a presentation policy, while PTC Plus owns the REPL, diagnosti
|
|
|
6
6
|
|
|
7
7
|
## Decision
|
|
8
8
|
|
|
9
|
-
Keep the current deterministic recovery policy in `internal/recovery-tips.js` as a replaceable local provider. The provider consumes the immutable facts produced by `internal/session-log-view.js`; it does not traverse raw events, pair calls, parse journals, or query the core through callbacks. The core calls it
|
|
9
|
+
Keep the current deterministic recovery policy in `internal/recovery-tips.js` as a replaceable local provider. The provider consumes the immutable facts produced by `internal/session-log-view.js`; it does not traverse raw events, pair calls, parse journals, or query the core through callbacks. The core calls it for one bounded named tip, delivered as an independent PTC notice under [ADR 0010](0010-session-log-derived-recovery-tips.md). The provider does not change execution, journal semantics, tool schemas, or stable system text. Defer an external adapter until a public facts and decision contract exists; the adapter must be optional, fail closed, and leave the local provider or disabled mode available when absent.
|
|
10
10
|
|
|
11
11
|
## Alternatives considered
|
|
12
12
|
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
# Preserve Mixed Destructuring Initialization
|
|
2
2
|
|
|
3
|
+
The historical behavior below is retained by the frozen `legacy-v1` compiler. New cells use the logical identities and complete declarator publication in [ADR 0025](0025-use-versioned-logical-binding-identities.md).
|
|
4
|
+
|
|
3
5
|
## Problem
|
|
4
6
|
|
|
5
7
|
Loose cross-cell redeclarations must assign names that already exist while introducing fresh names from one top-level destructuring declarator. A text-level whole-pattern assignment can preserve simple values, but it changes JavaScript binding initialization when a default expression refers to an earlier fresh binding, and a generated helper can also change top-level `await` or initializer ordering.
|
|
6
8
|
|
|
7
9
|
## Decision
|
|
8
10
|
|
|
9
|
-
`internal/repl-convenience.js` evaluates the initializer as a helper argument, then runs the original destructuring pattern unchanged inside the helper. This leaves initializer references outside the new pattern scope while the JavaScript engine owns binding order, TDZ, computed keys, defaults, iterator handling, lexical shadowing, and abrupt completion inside the pattern. After the complete pattern succeeds, the helper passes every bound value positionally to a commit callback: existing names are assigned to their session bindings and fresh values are returned to one outer declaration. Arrays carry the positional values so names such as `__proto__` have no property-key semantics. A pattern containing direct `await` uses an async helper; a synchronous pattern stays synchronous. Declarator replacements remain in source order, and both lexical and `var` mixed declarations use the same native-pattern model with their corresponding outer declaration kind.
|
|
11
|
+
`internal/legacy-repl-convenience.js` evaluates the initializer as a helper argument, then runs the original destructuring pattern unchanged inside the helper. This leaves initializer references outside the new pattern scope while the JavaScript engine owns binding order, TDZ, computed keys, defaults, iterator handling, lexical shadowing, and abrupt completion inside the pattern. After the complete pattern succeeds, the helper passes every bound value positionally to a commit callback: existing names are assigned to their session bindings and fresh values are returned to one outer declaration. Arrays carry the positional values so names such as `__proto__` have no property-key semantics. A pattern containing direct `await` uses an async helper; a synchronous pattern stays synchronous. Declarator replacements remain in source order, and both lexical and `var` mixed declarations use the same native-pattern model with their corresponding outer declaration kind.
|
|
10
12
|
|
|
11
13
|
## Alternatives considered
|
|
12
14
|
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
# Isolate REPL Redeclaration Convenience
|
|
2
2
|
|
|
3
|
+
The historical behavior below is retained by the frozen `legacy-v1` compiler. New cells use the logical identities and complete declarator publication in [ADR 0025](0025-use-versioned-logical-binding-identities.md).
|
|
4
|
+
|
|
3
5
|
## Problem
|
|
4
6
|
|
|
5
7
|
The persistent REPL uses one worker lexical environment so later cells can refer to earlier top-level bindings. That convenience is not JavaScript's module or function semantics. Mixed old/new destructuring needs a policy for combining declaration and assignment, while ordinary iterative work also needs an explicit policy for replacing an earlier function or class declaration. Keeping either policy inside `internal/cell-analysis.js` makes core parsing and durability analysis depend on one replaceable persistence strategy.
|
|
6
8
|
|
|
7
9
|
## Decision
|
|
8
10
|
|
|
9
|
-
`internal/cell-analysis.js` owns cell parsing, binding inventory, durability classification, return rewriting, and execution preparation. Shared binding-pattern traversal lives in `internal/binding-pattern.js`. `internal/repl-convenience.js` owns two independent, optional cross-cell policies: variable replacement (including mixed destructuring lowering) and named function/class replacement. It returns executable source, collisions, redeclaration metadata, and rewrite provenance through one narrow function.
|
|
11
|
+
`internal/legacy-cell-analysis.js` owns legacy cell parsing, binding inventory, durability classification, return rewriting, and execution preparation. Shared binding-pattern traversal lives in `internal/binding-pattern.js`. `internal/legacy-repl-convenience.js` owns two independent, optional cross-cell policies: variable replacement (including mixed destructuring lowering) and named function/class replacement. It returns executable source, collisions, redeclaration metadata, and rewrite provenance through one narrow function. Both policies are enabled by default for the REPL workflow; function/class replacement can still be explicitly disabled with `looseTopLevelFunctionClassRedeclarations`.
|
|
10
12
|
|
|
11
13
|
Only a top-level named `FunctionDeclaration` or `ClassDeclaration` whose name existed before preparation is eligible. Its catalog provenance must prove that the existing binding is writable: `let`, `var`, function, and class are writable; a source `const` is writable only when that cell's variable policy lowered it to `let`; imports and reserved/private bindings are not writable. Unknown provenance fails closed. A function is lowered at its declaration position to assignment of an anonymous function expression, so recursive reads resolve through the replaceable outer binding. A class is lowered to assignment of a named class expression, preserving its inner self-reference and ensuring a throw during class evaluation leaves the old outer value unchanged. Both forms deliberately take effect at the declaration position rather than acquiring native declaration hoisting. A terminated `void 0` statement prevents the assignment value from becoming the cell completion.
|
|
12
14
|
|
|
@@ -6,9 +6,13 @@ Durable replay prepares the original cell source again. AST module rewrites and
|
|
|
6
6
|
|
|
7
7
|
## Decision
|
|
8
8
|
|
|
9
|
+
The module-lowering fields below retain the `legacy-v1` contract. Journal v9 additionally selects the complete language through `languageSemantics`; its `stateful-v1` and `protected-v1` contracts are owned by [ADR 0025](0025-use-versioned-logical-binding-identities.md). A historical `live-readonly` field does not independently make a stateful binding read-only.
|
|
10
|
+
|
|
9
11
|
Journal version 4 replaces `bindingMode` with the closed `bindingPolicy` object containing the exact `variableRedeclarations` and `functionClassRedeclarations` booleans used to prepare the cell. It retains `rewritePolicy` with the three module and mixed-declaration rewrite booleans, and adds the closed `moduleSemantics.defaultExportBinding` value. Current cells record `live-readonly`; this is a source-lowering generation, not a user setting. Live journals capture both active policies and the fixed module semantics; replay passes every recorded value to `prepareProgram`. These objects participate in normalization and semantic equality, are frozen with the journal, and are required by the closed schema. A profile change therefore affects only new cells; existing durable nodes retain the language policy, module lowering, and writable-binding provenance under which they were evaluated.
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
Journal version 7 adds the closed `moduleSemantics.importExpressionBoundary` value, which is orthogonal to the default-export binding model and fixes how a module-reference write is lowered relative to its preceding statement. Current cells record `statement-safe`: the lowered write keeps its own statement boundary, so automatic semicolon insertion cannot merge it into a preceding semicolonless expression and change which value receives the write or whether the write runs at all. Versions 1 through 6 normalize to `legacy` so historical cells replay the lowering generation that evaluated them instead of the current one. The value participates in normalization, freezing, and semantic equality like the other closed semantics fields.
|
|
14
|
+
|
|
15
|
+
The journal decoder also owns the predecessor adapters. Versions 1 through 3 retain their original closed field sets as inputs and normalize forward through the closed generations. Their `bindingMode` maps exactly to `variableRedeclarations`; `functionClassRedeclarations` is always `false` because those language pipelines did not implement the feature. They receive `legacy-variable` default-export semantics so loose journals preserve the historically writable generated binding and strict journals preserve its const behavior. Version 1 receives all three later rewrite switches as disabled and its string call-ID confirmations become event sequences only when the enclosing session log contains exactly one earlier unjournaled `run_code` call with that identity. Missing or repeated candidates are ambiguous, so they cannot prove old state and form an unknown recovery boundary. Versions 2 and 3 retain their recorded `rewritePolicy`; unsupported non-numeric predecessor confirmations receive the same conservative contraction. Each later generation extends the same chain: version 4 records no Global User Binding relation, version 5 adds the snapshot fingerprint, version 6 adds `userBindingsReusePolicy`, version 7 adds `importExpressionBoundary`, and version 8 adds the per-name shadow policy with its name evidence, owned by [ADR 0023](0023-global-user-bindings.md). Version 9 adds the required complete language generation, with versions 1 through 8 fixed to the frozen legacy compiler rather than reinterpreted by current lowering ([ADR 0025](0025-use-versioned-logical-binding-identities.md)). Per [ADR 0007](0007-separate-worker-transport-from-session-semantics.md), rejecting predecessor state evidence does not make historical metadata an availability gate for the current valid call.
|
|
12
16
|
|
|
13
17
|
## Alternatives considered
|
|
14
18
|
|
|
@@ -24,4 +28,4 @@ The journal decoder also owns the predecessor adapters. Versions 1 through 3 ret
|
|
|
24
28
|
|
|
25
29
|
## Consequences
|
|
26
30
|
|
|
27
|
-
The
|
|
31
|
+
The journal schema introduced by this decision is version 4; the closed field sets, generation constants, and migration rules are owned by [`internal/session-journal-schema.js`](../../internal/session-journal-schema.js), with validation, migration, and creation in [`internal/session-journal.js`](../../internal/session-journal.js) and event association and fold/recovery in [`internal/session-journal-recovery.js`](../../internal/session-journal-recovery.js). Replay remains source-based and deterministic across configuration changes without invalidating durable cells or altering reconstructed binding assignability. Version 1 histories retain the predecessor rewrite behavior and migrate only uniquely identified confirmations; versions 2 and 3 retain their recorded rewrite policy. Versions 1 through 3 fix function/class replacement to disabled and default-export lowering to `legacy-variable`; versions 1 through 6 fix the import-expression boundary to `legacy`. Later records preserve their independently recorded values instead of guessing from current behavior. Ambiguous identity remains unsupported recovery input rather than receiving guessed defaults. New profile settings apply at the next live cell boundary.
|
|
@@ -6,7 +6,7 @@ PTC cells are prepared by several source-to-source passes before they reach the
|
|
|
6
6
|
|
|
7
7
|
## Decision
|
|
8
8
|
|
|
9
|
-
Each source edit carries a compact segment map from generated text back to the original cell. Unchanged text retains exact offsets; generated module bindings and source literals carry token-level anchors to their originating AST nodes, while other introduced text maps to the replaced source span. [`internal/source-position-map.js`](../../internal/source-position-map.js) validates and sorts one pass of non-overlapping edits, then assembles source and composed segments in one traversal. Binary segment lookup handles repeated or non-monotonic explicit token anchors without rescanning the complete map. Maps compose through every preparation pass. Mixed-destructuring generation emits copied pattern, initializer, and binding ranges through the same mapped representation instead of one opaque replacement string. [`internal/cell-analysis.js`](../../internal/cell-analysis.js)
|
|
9
|
+
Each source edit carries a compact segment map from generated text back to the original cell. Unchanged text retains exact offsets; generated module bindings and source literals carry token-level anchors to their originating AST nodes, while other introduced text maps to the replaced source span. [`internal/source-position-map.js`](../../internal/source-position-map.js) validates and sorts one pass of non-overlapping edits, then assembles source and composed segments in one traversal. Binary segment lookup handles repeated or non-monotonic explicit token anchors without rescanning the complete map. Maps compose through every preparation pass. Mixed-destructuring generation emits copied pattern, initializer, and binding ranges through the same mapped representation instead of one opaque replacement string. [`internal/cell-parser.js`](../../internal/cell-parser.js) is the single executable-parse entry: it relocates AST ranges to original-cell coordinates and reports parse failures in those coordinates, so no downstream pass applies a wrapper offset. [`internal/cell-analysis.js`](../../internal/cell-analysis.js) maps parse failures raised against the module-rewrite output, preflight spans, and collision spans back to original-cell coordinates before returning a prepared program; runtime exception positions use the same map after worker execution, except a module-load failure that already carries an original-cell position.
|
|
10
10
|
|
|
11
11
|
## Alternatives considered
|
|
12
12
|
|
|
@@ -10,7 +10,7 @@ An ignored root `REVIEW_FINDINGS.md` prevents unresolved review findings from be
|
|
|
10
10
|
|
|
11
11
|
Review output and ledger mutation follow task authority. A read-only review reports records in the ledger's semantic fields without writing checkout state. Every implementation preserves an active ledger, but an ordinary change with no finding does not create one. `npm run review:new` creates the ignored root ledger only when a task authorizes capture or resolution of at least one finding; implementation imports those findings before editing their fixes. Archives move under Git's local `review-findings/archive` metadata path, so they cannot enter a commit and remain associated with the checkout.
|
|
12
12
|
|
|
13
|
-
Ledger validation, readiness, deterministic verification, archive, and commit proof are distinct states with one implementation. `npm run review:validate` checks schema and tracked-file safety while accepting a valid open ledger. `npm run review:gate` is read-only: it blocks an open ledger, validates durable owners for accepted findings, and never archives. `npm run verify` performs schema validation before syntax and coverage checks, so open-ledger work can collect evidence. `npm run check` applies the readiness gate first, then materializes the current tracked and non-ignored checkout through Git's clean and index semantics in a temporary Git administrative directory. Git selects that directory's default index through `--git-dir` and reads the target checkout through `--work-tree`; it never receives an alternate-index environment path that could fall back to the real repository index. The temporary object database reads the repository's objects through a relative alternates entry and stores new fingerprint objects locally. The resulting tree object ID includes canonical blobs, symlink identity, and file modes while remaining independent of staged content. Sparse checkouts retain skip-worktree paths from the `HEAD` baseline and apply clean conversion only to materialized paths, so an absent out-of-cone file is neither lost nor mistaken for a deletion. Every path discovered by Git is reapplied through NUL-delimited literal input. The command separately snapshots the ignored ledger, runs `verify`, rejects changed source or ledger state, and refreshes the proof before archiving a resolved ledger. Repository scripts that launch npm as a child use one command resolver: an invoking npm process supplies its CLI path and Node executable, while direct script invocation falls back to the platform npm executable. A successful later check without an active ledger also refreshes an older proof. The pre-commit hook rejects open and unverified resolved ledgers,
|
|
13
|
+
Ledger validation, readiness, deterministic verification, archive, and commit proof are distinct states with one implementation. `npm run review:validate` checks schema and tracked-file safety while accepting a valid open ledger. `npm run review:gate` is read-only: it blocks an open ledger, validates durable owners for accepted findings, and never archives. `npm run verify` performs schema validation before syntax and coverage checks, so open-ledger work can collect evidence. `npm run check` applies the readiness gate first, then materializes the current tracked and non-ignored checkout through Git's clean and index semantics in a temporary Git administrative directory. Git selects that directory's default index through `--git-dir` and reads the target checkout through `--work-tree`; it never receives an alternate-index environment path that could fall back to the real repository index. The temporary object database reads the repository's objects through a relative alternates entry and stores new fingerprint objects locally. The resulting tree object ID includes canonical blobs, symlink identity, and file modes while remaining independent of staged content. Sparse checkouts retain skip-worktree paths from the `HEAD` baseline and apply clean conversion only to materialized paths, so an absent out-of-cone file is neither lost nor mistaken for a deletion. Every path discovered by Git is reapplied through NUL-delimited literal input. The command separately snapshots the ignored ledger, runs `verify`, rejects changed source or ledger state, and refreshes the proof before archiving a resolved ledger. Repository scripts that launch npm as a child use one command resolver: an invoking npm process supplies its CLI path and Node executable, while direct script invocation falls back to the platform npm executable. A successful later check without an active ledger also refreshes an older proof. The pre-commit hook rejects open and unverified resolved ledgers, requires a verification proof for the current `HEAD`, requires equal source and index tree fingerprints, and requires a clean independent-review verdict bound to the same `HEAD`, fingerprint and scope (ADR 0026). Staging the complete verified tree permits repeated commit attempts; partial staging, additional staged content, mode-only changes, or later checkout changes require reconciliation or another checked workflow. An advanced HEAD, a missing proof, or a verdict that does not match the verified candidate retires the stale evidence and blocks the commit.
|
|
14
14
|
|
|
15
15
|
Hook installation is explicit. `npm run hooks:install` selects the tracked hook path only when the effective `core.hooksPath` is unset or already `.githooks`. Before the first switch from Git's default hooks directory, installation rejects any non-sample hook file there; it also rejects an incompatible configured path instead of disabling another hook owner. Dependency installation has no Git-configuration side effect.
|
|
16
16
|
|
|
@@ -6,8 +6,55 @@ PTC Plus integrates with DSH services, request bindings, prompt assembly, sessio
|
|
|
6
6
|
|
|
7
7
|
## Decision
|
|
8
8
|
|
|
9
|
+
PTC Plus must remain independently installable on unmodified official DSH distributions. Host source is read-only research evidence, not an implementation workspace for plugin features. Plugin changes must not patch host source or installed packages, introduce install-time host patches, or require a custom host build. Plugin-owned components, panels, styling, portals and public renderer replacements are valid UI choices within the consumed contracts; integration does not require every visual element or layout to be native. A locally invented extension declaration is not a published public capability. Choose among published surfaces according to the required user experience rather than assuming that a UI feature must become a historical message node. If none can satisfy the required behavior, record the actual limitation; do not substitute a custom distribution or present a compatibility fallback as delivery.
|
|
10
|
+
|
|
9
11
|
The compatibility target is the latest available DSH release. Production behavior, configuration, tests, installation guidance, and current compatibility claims depend on public extension contracts and observed live schemas, never on a DSH version allowlist or comparison. An upstream default projection is not an extension ceiling: when public scoped registration and presentation support a plugin-owned capability, PTC Plus preserves that capability and its model-visible identity instead of deleting or renaming it to match the default. Deterministic normalization remains valid for a call that is outside the declared direct surface when the live schema proves one native target and the lowering preserves arguments, call identity, authority, and result semantics. Deterministic tests exercise the consumed contracts; model-backed and packaging acceptance runners use the installed DSH and record `dsh --version` in generated reports so failures remain attributable without turning the observed value into policy. Concrete DSH release numbers may appear only in source comments that identify historical integration or evaluation evidence and cannot influence execution or acceptance.
|
|
10
12
|
|
|
13
|
+
Preceding public contracts remain supported where capability detection is
|
|
14
|
+
unambiguous. Tools presentation is selected by the installed public schema;
|
|
15
|
+
Client contributions depend on their slots and supplied hooks rather than unused
|
|
16
|
+
package gates. Preset projection evidence takes precedence over the preceding
|
|
17
|
+
public session-summary field, and the current composer currency takes precedence
|
|
18
|
+
over the earlier session/interactions currency. This compatibility does not
|
|
19
|
+
extend to private stores or inferred binding state.
|
|
20
|
+
|
|
21
|
+
Compatibility decisions have one owner per public contract and execution
|
|
22
|
+
environment. `src/client-host-compat.js` owns Client preset reads and subscriptions
|
|
23
|
+
and composer compatibility. UI consumers own feature eligibility and slot
|
|
24
|
+
registration. `scripts/dsh-host-contract.mjs` owns selected-installation package
|
|
25
|
+
resolution, tools presentation and persona field adaptation for development and
|
|
26
|
+
acceptance commands. Host runtime contracts remain in their existing focused
|
|
27
|
+
owners, including `internal/session-events.js`, `internal/settings-compat.js`, and
|
|
28
|
+
`internal/execution-seam-compat.js`, which owns which program-execution service the
|
|
29
|
+
plugin attaches to and the call shape and provider descriptors it presents for it
|
|
30
|
+
([ADR 0028](0028-attach-to-the-host-ptc-execution-seam.md)).
|
|
31
|
+
`internal/host-rpc.js` owns UI Remote service registration and withdrawal;
|
|
32
|
+
`src/client-rpc.js` owns Client mounting and result unwrapping. Both consume the
|
|
33
|
+
executable wire definitions in `internal/rpc-contract.js`. Binding and observation
|
|
34
|
+
owners supply operation handlers and retain their domain validation. Consumers
|
|
35
|
+
use these operations instead of repeating transport or field-generation checks.
|
|
36
|
+
Adapters preserve unknown evidence and public subscription disposal; they do not
|
|
37
|
+
cache session capabilities globally. Test-only persistence fixtures and explicit
|
|
38
|
+
offline journal migration retain their own lifecycles and validation contracts.
|
|
39
|
+
|
|
40
|
+
## UI communication
|
|
41
|
+
|
|
42
|
+
Plugin UI calls use DSH's public Typert Remote and Gateway over the existing
|
|
43
|
+
`/api` carrier. The shared contract defines `ptcPlusBindings.invoke` and
|
|
44
|
+
`ptcPlusRepl.invoke`, each with an operation string, JSON payload, optional
|
|
45
|
+
cancellation signal and the domain result envelope. The Client unwraps only the
|
|
46
|
+
Gateway result layer. The Host owns authentication, origin checks, transport
|
|
47
|
+
cancellation and dispatch; a connection identity does not confer a draft locator.
|
|
48
|
+
|
|
49
|
+
The communication owner contributes one package definition containing the active
|
|
50
|
+
services. Disabling Global User Bindings withdraws its service and invocation;
|
|
51
|
+
REPL observation has its own eligibility checks. Service removal aborts pending
|
|
52
|
+
calls and invalidates retained references. Provider replacement cancels the old
|
|
53
|
+
requests and republishes active definitions through Cordis injection. Client
|
|
54
|
+
Remote mounting belongs to its calling fiber and is released with that fiber.
|
|
55
|
+
Writes are never retried by the adapter. Business owners preserve revision,
|
|
56
|
+
capability, storage and observation rules independently of transport.
|
|
57
|
+
|
|
11
58
|
## Alternatives considered
|
|
12
59
|
|
|
13
60
|
**Pin one verified DSH release.** A pin makes one historical environment reproducible but turns normal upstream progress into an artificial incompatibility and allows the implementation to drift from the release users actually install.
|
|
@@ -20,4 +67,6 @@ The compatibility target is the latest available DSH release. Production behavio
|
|
|
20
67
|
|
|
21
68
|
## Consequences
|
|
22
69
|
|
|
70
|
+
Feature completion requires evidence from the actual packaged plugin running on the selected unmodified Host, including the affected user flow. Component fixtures and public-interface unit tests validate narrower properties; they do not prove that a required renderer exists or is loaded in that distribution. A clean code review and passing deterministic checks are separate from product acceptance. Both must cover the final change before a feature is described as delivered; commit and publish authorization remain separate user decisions.
|
|
71
|
+
|
|
23
72
|
Each upstream DSH release becomes the immediate compatibility target and must pass the public-surface, packaging, and model-backed checks appropriate to the change. Users are not blocked by stale version metadata. Historical reports remain attributable through generated runtime metadata or source comments, while a passing older run never substitutes for validation against the latest release.
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
## Problem
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Using the active PTC Plus checkout as each ordinary-task A/B arm's workload would make the workload change whenever the plugin repository grows, destabilizing absolute machine budgets and longitudinal comparisons. It would also make one source tree serve as the host, treatment-under-test workspace, and measurement workload, mixing unrelated variables into one measurement.
|
|
6
6
|
|
|
7
7
|
## Decision
|
|
8
8
|
|
|
9
|
-
The primary ordinary-task A/B workload is
|
|
9
|
+
The primary ordinary-task A/B workload is a purpose-built, versioned, zero-dependency Node.js fixture in `fixtures/ab-node-project-v1`. The fixture manifest is the single owner of the fixture name, version, content SHA-256, deterministic Git identity/commit, and deterministic dirty state. The runner materializes the fixture independently into each arm workspace, initializes the same deterministic Git history, applies the same uncommitted changes, and never copies the active PTC Plus checkout as the model workload.
|
|
10
10
|
|
|
11
11
|
The A/B task set contains a fixed, cheap, machine-checkable canary that exercises `run_code` before the full paired matrix starts. Reports record the fixture path, version, and content hash so future runs are grouped by benchmark version. The current PTC Plus checkout is kept as a separate self-hosting acceptance surface; it is not the stable README headline benchmark.
|
|
12
12
|
|
|
@@ -22,4 +22,4 @@ The A/B task set contains a fixed, cheap, machine-checkable canary that exercise
|
|
|
22
22
|
|
|
23
23
|
## Consequences
|
|
24
24
|
|
|
25
|
-
The benchmark workload is stable under unrelated PTC Plus source changes and has its own result series tied to `fixtureVersion` and content hash.
|
|
25
|
+
The benchmark workload is stable under unrelated PTC Plus source changes and has its own result series tied to `fixtureVersion` and content hash. Results produced from an active-checkout workload are not comparable to the versioned-fixture series. Maintaining the benchmark requires updating the fixture manifest together with the fixture content, and a materially different task set or fixture change starts a new series rather than reusing old totals.
|
|
@@ -14,9 +14,11 @@ PTC Plus 0.1.0 deliberately had no Client UI. The runtime surface was the DSH PT
|
|
|
14
14
|
|
|
15
15
|
PTC Plus registers one DSH settings namespace `ptc-plus` with the same field list, defaults and validation as the Host Config schema. The field definitions live once in `internal/config-spec.js`; `index.js` builds the Cordis Config schema from it, and the esbuild client bundle imports the same module so the UI does not copy defaults or validation.
|
|
16
16
|
|
|
17
|
-
The settings card
|
|
17
|
+
The settings card's seat is generation-owned. The preceding DSH declares `settings.plugin.item` (keyed, root) in its Settings panel and renders one card per served namespace; the current one renders a bundle's own configuration on its side-bar Plugins page through `plugins.row.config` (keyed, root) as `<bundle package name>#<row id>` and reserves `plugins.item` for the host-plane pages DSH itself ships. `src/client-host-compat.js` owns both seats and publishes the card to both, because `ctx.slots.inject` waits while a key is undeclared and neither generation declares the other's key; the declaring generation therefore decides which single seat renders the card. The composer shortcut opens an application-modal rendering of the same complete form, so direct access does not depend on a host page's component-local navigation state; its hover hint still names the native seat available on that generation.
|
|
18
18
|
|
|
19
|
-
The
|
|
19
|
+
The settings card places the plugin switch first, then groups controls by purpose: tool call tolerance, REPL syntax, state and recovery, tool extensions, interface display, and resource limits. Recovery tips and their thresholds stay together, and global binding management appears directly below its enable switch. `CONFIG_GROUPS` owns this presentation order independently of Host schema field order and defaults. `autoDescribeRunCode` defaults to true and controls only a request-bound local execution policy. When enabled, a call that omits the outer `description` uses derived arguments for local DSH validation, and the fallback summary enters presentation metadata only; when disabled, DSH validates the original arguments. Both states produce byte-stable model-visible tool schemas, order, and system sections with the required `description` declaration. Original call arguments, explicit summaries, cell source, and nested native-tool arguments remain unchanged.
|
|
20
|
+
|
|
21
|
+
The configurable set is the Host runtime configuration plus `enabled: boolean` (default true). `enabled` is the kill switch: when false the Host keeps the settings namespace, client card, and passive message cleanup defined in [ADR 0010](0010-session-log-derived-recovery-tips.md). The next permitted accepted step may clear earlier PTC declarations. It does not install the runtime bridge, edit transport, direct-surface owner, system prompt section, tool registrations, or execution hooks, and does not read binding storage. When true the same runtime as pre-settings PTC Plus is installed. Every field is live when its owner can reconcile it: the Host observes the settings scope and installs, uninstalls, or reconfigures owners without replacing existing session-bound bindings. Node fixes a worker's V8 `maxOldGenerationSizeMb` limit at construction, so changing that field while a session worker is active is rejected and the settings provider is restored to the previous value; other reconfiguration failures use the same compensation path. The TypeScript language check occurs at activation, allowing disabled settings to load on a host using another code runtime while rejecting and rolling back an enable attempt. If the settings service is absent, the Host falls back to composition config and enables the runtime.
|
|
20
22
|
|
|
21
23
|
Every settings-card and PTC Plus tool-row string is registered into the DSH client locale namespace `settings.ptcPlus` and follows the active DSH client locale. Field copy exists in both locales from the single `internal/config-spec.js` source (`label`/`labelEn`, `description`/`descriptionEn`); display chrome copy is owned by the Client half. The stable REPL guidance remains plugin-owned protocol text without UI branding. The transport names remain `run_code`/`edit_run_code`; DSH owns their identity.
|
|
22
24
|
|
|
@@ -35,7 +37,7 @@ Runtime activation is transactional. If a live enable cannot complete, every own
|
|
|
35
37
|
## Alternatives Considered
|
|
36
38
|
|
|
37
39
|
1. Keep no Client UI. Rejected: PTC Plus requires a settings surface and a kill switch. Away from settings, users cannot tell whether PTC Plus is actively installed because the only marker is application behavior.
|
|
38
|
-
2. Rely on DSH generic schema rendering without a
|
|
40
|
+
2. Rely on DSH generic schema rendering without a settings-card seat. Rejected: the generic tab renders only namespace cards supplied through the slot; shipping no card would leave the namespace invisible even though the schema is registered.
|
|
39
41
|
3. Rename the `run_code` tool or use a schema/name-level UI alias. Rejected: PTC Plus must preserve the DSH host tool names and their public pipeline semantics; presentation labels belong in Client-owned UI, not in transport identity or model-visible stable text.
|
|
40
42
|
4. Keep non-`enabled` fields restart-applied. Rejected: a settings UI that persists values without changing the active runtime is misleading. Runtime owners now accept live configuration updates; session kernels keep their bindings while applying new limits and policies to subsequent cells.
|
|
41
43
|
5. Keep the card copy Chinese-only, or let the card branch on the browser locale itself. Rejected: the plugin's own copy must follow the same Host-owned locale preference every other settings surface follows, so it registers both dictionaries under `settings.ptcPlus` and uses the `t` seat composed by the DSH slot renderer; duplicating per-locale text outside `internal/config-spec.js` would break the single-source rule for field copy.
|
|
@@ -14,9 +14,9 @@ Tool registration must finish before the prompt assembly returned to the agent;
|
|
|
14
14
|
|
|
15
15
|
## Decision
|
|
16
16
|
|
|
17
|
-
Add `cordisToolsEnabled: boolean`, default `false`, as a live PTC Plus setting. When enabled, PTC Plus mounts the official `@deepseek-ai/dsh-tool-cordis` plugin and a maintained `@deepseek-ai/dsh-skill-filesystem` provider in each agent scope that exposes `run_code
|
|
17
|
+
Add `cordisToolsEnabled: boolean`, default `false`, as a live PTC Plus setting. When enabled, PTC Plus mounts the official `@deepseek-ai/dsh-tool-cordis` plugin and a maintained `@deepseek-ai/dsh-skill-filesystem` provider in each agent scope that exposes every surface the mount publishes through: `run_code`, the `skill` tool, and the public `agentPresets` and `skills` services; disabling it disposes both fibers immediately. The provider resolves the shipped `cordis` preset through the public `agentPresets` service and reads its sibling `skills` root without including default roots. At the public `skills.registerProvider` seam, PTC Plus transparently filters discovery and loading to exactly `cordis-plugin-development`; the maintained filesystem provider still owns parsing, resource bases, watch, invalidation, incomplete observations, and body loading. This prevents unrelated or obsolete sibling Skills from silently enlarging the PTC surface without copying the companion content or switching the current preset. A scope that omits one of those surfaces is not an error: the owner keeps the agent pending, publishes nothing there, and retries on the DSH tools-change signal or the next prompt assembly, because a later registration or provided service can supply the missing member ([ADR 0029](0029-keep-plugin-unavailability-out-of-the-host-agent-lifecycle.md)).
|
|
18
18
|
|
|
19
|
-
The Skill provider and official Cordis child fiber form one reversible mount. Both must settle, and the scoped `skills` service must prove that `cordis-plugin-development` resolves from the added provider as model-invocable and loadable, before the first prompt assembly is returned. A prepended public `system-prompt/assemble` waterfall listener is the final race barrier: if collection began before the mount settled, it waits for readiness, discards that stale assembly, and invokes public assembly again so DSH recollects the official providers. It does not synthesize or mutate Cordis schemas or guidance. The Cordis fiber's resolved `inject` declaration is the authoritative required-service list, and its live registrations are the authoritative tool names, schemas, and guidance. A
|
|
19
|
+
The Skill provider and official Cordis child fiber form one reversible mount. Both must settle, and the scoped `skills` service must prove that `cordis-plugin-development` resolves from the added provider as model-invocable and loadable, before the first prompt assembly is returned. A prepended public `system-prompt/assemble` waterfall listener is the final race barrier: if collection began before the mount settled, it waits for readiness, discards that stale assembly, and invokes public assembly again so DSH recollects the official providers. It does not synthesize or mutate Cordis schemas or guidance. The Cordis fiber's resolved `inject` declaration is the authoritative required-service list, and its live registrations are the authoritative tool names, schemas, and guidance. A scope whose exposed preset, Skill service/tool, declared service, publication, or child fiber contradicts the DSH contract is a configuration error and rolls back every contribution; an absent surface only defers the mount. An unusable scope reached through the host's own calls — `agent/created` and the prepended waterfall — withdraws and reports one warning instead of failing the host operation that created the scope ([ADR 0029](0029-keep-plugin-unavailability-out-of-the-host-agent-lifecycle.md)).
|
|
20
20
|
|
|
21
21
|
The official plugin also registers Host inspect providers in the process-global `cordisInspect` service. Per-agent fibers therefore acquire owner-scoped leases for identical provider manifests instead of registering the same provider ID independently. Queries delegate to a registration from a still-live official fiber, and the process-global provider is removed when the final lease is released. A manifest mismatch remains a configuration error rather than silently choosing one contract.
|
|
22
22
|
|
|
@@ -30,6 +30,18 @@ append/flush queue. Legacy `ptc-plus/recovery-boundary` artifacts therefore
|
|
|
30
30
|
remain an explicit, startup-before-restore migration concern rather than a
|
|
31
31
|
runtime event handler concern.
|
|
32
32
|
|
|
33
|
+
Host format upgrades are also explicit pre-restore work. The migration CLI may
|
|
34
|
+
resolve the selected Host's public Session format catalog and use its strict
|
|
35
|
+
conversion and current validation. PTC result metadata remains opaque to that
|
|
36
|
+
catalog. The CLI therefore proves an ordered one-to-one relation between the
|
|
37
|
+
unchanged tool records, remaps only PTC-owned sequence references, and validates
|
|
38
|
+
the resulting timeline. Original call arguments and recorded effects are never
|
|
39
|
+
rewritten or executed. Ambiguous records, invalid PTC evidence and mixed retired
|
|
40
|
+
event conversions are refused. The source artifact remains intact and output
|
|
41
|
+
uses the target Host's encoder; already-renumbered metadata requires a retained
|
|
42
|
+
predecessor rather than inference from numeric values. See the
|
|
43
|
+
[upgrade procedure](../installation.md#session-format-upgrades).
|
|
44
|
+
|
|
33
45
|
The EasyRewrite host/client split is an architectural reference only; its
|
|
34
46
|
session and workspace UI APIs are not a persistence recovery mechanism.
|
|
35
47
|
|