dsh-ptc-plus 0.4.2 → 0.4.3

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 (83) hide show
  1. package/README.en.md +166 -76
  2. package/README.md +167 -77
  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-icon.svg +5 -0
  6. package/client.js +593 -306
  7. package/compiler-core.cjs +162 -160
  8. package/compiler-core.cjs.map +3 -3
  9. package/docs/README.md +3 -1
  10. package/docs/adr/0005-temporary-rejected-cell-edit-transport.md +8 -7
  11. package/docs/adr/0008-define-agent-operating-contract.md +2 -2
  12. package/docs/adr/0010-session-log-derived-recovery-tips.md +7 -0
  13. package/docs/adr/0016-archive-resolved-review-findings.md +3 -3
  14. package/docs/adr/0019-plugin-settings-and-kill-switch.md +3 -3
  15. package/docs/adr/0020-optional-cordis-tools-in-ptc-mode.md +2 -0
  16. package/docs/adr/0021-separate-host-bootstrap-from-session-runtime.md +14 -3
  17. package/docs/adr/0023-global-user-bindings.md +1 -1
  18. package/docs/adr/0026-persist-the-delivery-verdict-against-the-verified-candidate.md +23 -7
  19. package/docs/adr/0027-run-the-session-kernel-in-a-killable-helper-process.md +4 -0
  20. package/docs/adr/0028-attach-to-the-host-ptc-execution-seam.md +26 -6
  21. package/docs/adr/0031-close-semantic-obligations-by-owner.md +29 -0
  22. package/docs/adr/README.md +4 -4
  23. package/docs/architecture.md +6 -5
  24. package/docs/binding-review-placement-design.md +1 -1
  25. package/docs/client-ui.md +8 -4
  26. package/docs/durability-design.md +7 -7
  27. package/docs/installation.md +26 -8
  28. package/docs/runtime-reference.md +18 -11
  29. package/docs/semantic-validation.md +7 -3
  30. package/docs/user-bindings.en.md +7 -6
  31. package/docs/user-bindings.md +6 -5
  32. package/docs/value-wire.md +1 -1
  33. package/docs/verification.md +38 -1
  34. package/index.js +39 -34
  35. package/internal/async-local-storage-intrinsics.js +12 -7
  36. package/internal/callable-source-facts.js +37 -1
  37. package/internal/cell-analysis.js +64 -9
  38. package/internal/config-spec.js +1 -1
  39. package/internal/cordis-tools-owner.js +20 -10
  40. package/internal/edit-transport-owner.js +80 -20
  41. package/internal/execution-seam-compat.js +192 -30
  42. package/internal/kernel-worker.js +162 -72
  43. package/internal/message-sources.js +14 -0
  44. package/internal/module-compilation.js +2 -1
  45. package/internal/repl-memory-projection.js +10 -0
  46. package/internal/repl-scope-normalizer.js +72 -35
  47. package/internal/repl-value-observer.js +141 -45
  48. package/internal/runtime-config.js +62 -2
  49. package/internal/runtime-intrinsics.js +3 -0
  50. package/internal/runtime-messages.js +6 -4
  51. package/internal/session-cell-executor.js +24 -1
  52. package/internal/session-journal-recovery.js +267 -67
  53. package/internal/session-journal.js +466 -40
  54. package/internal/session-log-view.js +5 -4
  55. package/internal/session-runtime.js +45 -21
  56. package/internal/session-state.js +7 -29
  57. package/internal/settings-compat.js +66 -1
  58. package/internal/source-position-map.js +19 -0
  59. package/internal/user-binding-console-worker.js +23 -9
  60. package/internal/user-binding-draft-projection.js +3 -2
  61. package/internal/user-bindings-owner.js +2 -1
  62. package/internal/user-bindings.js +6 -1
  63. package/internal/validated-parse-repair.js +6 -2
  64. package/internal/value-wire.js +95 -30
  65. package/internal/worker-client.js +99 -8
  66. package/internal/worker-cwd-virtualization.js +10 -9
  67. package/internal/worker-output-capture.js +187 -0
  68. package/internal/worker-output-fence.js +26 -0
  69. package/internal/worker-realm-surfaces.js +197 -0
  70. package/internal/worker-repl-realm.js +10 -4
  71. package/package.json +36 -4
  72. package/src/client-activity.js +4 -1
  73. package/src/client-authoring-view.js +121 -62
  74. package/src/client-console.js +4 -2
  75. package/src/client-copy.js +4 -2
  76. package/src/client-feature-gates.js +7 -9
  77. package/src/client-host-compat.js +104 -27
  78. package/src/client-repl-view.js +3 -1
  79. package/src/client-styles.js +12 -1
  80. package/src/client-tool-view.js +3 -1
  81. package/src/client-transport.js +2 -2
  82. package/src/client-workbench.js +4 -3
  83. package/src/client.js +56 -17
package/docs/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## Getting Started
4
4
 
5
- - [Installation](installation.md): npm, Git, source, tarball, development snapshot, and Desktop installation.
5
+ - [Installation](installation.md): npm, Git, source, tarball, development snapshot, and Desktop installation, plus upgrades, troubleshooting, and Session format migration.
6
6
  - [Global binding guide](user-bindings.en.md) ([中文](user-bindings.md)): author, review, save, configure, and test reusable helpers.
7
7
  - [Runtime Reference](runtime-reference.md): cell behavior, capability discovery, configuration, diagnostics, and limits.
8
8
  - [Evaluation](evaluation.md): paired ordinary-task protocol, metrics, configuration, and limitations.
@@ -17,11 +17,13 @@
17
17
  - [Global User Bindings](adr/0023-global-user-bindings.md): persistent helper ownership, model projection, runtime activation, recovery, and Agent-assisted authoring.
18
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
19
  - [Logical Binding Identities](adr/0025-use-versioned-logical-binding-identities.md): stateful declarations, scope, candidate publication and language generations.
20
+ - [Stateful Binding Updates](stateful-binding-updates-proposal.md): target stateful-computation semantics and their acceptance boundaries.
20
21
  - [Architecture Decisions](adr/): stable design constraints and their consequences.
21
22
 
22
23
  ## Maintenance
23
24
 
24
25
  - [Deterministic Verification](verification.md): complete checks, backend test concurrency, coverage, and focused diagnostics.
26
+ - [Incremental Review Verdict](adr/0026-persist-the-delivery-verdict-against-the-verified-candidate.md): predeclared parallel lanes, dependency-scoped invalidation, and the composite commit verdict.
25
27
  - [Focused Verification](verification-optimization-work.md): bounded coverage diagnostics and their relationship to the final verification gate.
26
28
  - [Semantic Validation](semantic-validation.md): pinned Test262 cases, dialect contracts, native differential matrices and their limits.
27
29
  - [Publishing](publishing.md): release checks, package contents, permissions, and platform validation.
@@ -23,9 +23,10 @@ edit_run_code({
23
23
 
24
24
  PTC mode requests using the code-only direct-tool projection expose `[run_code, edit_run_code]` in
25
25
  that order. The first conclusive prompt assembly creates one per-agent composition owner before any
26
- plugin-owned presentation effect changes the nearest DSH scope. A non-empty `tools:code-only`
27
- section proves `code`, an empty section proves `both`, and only a missing owner signal permits a
28
- tool-shape inference. For a code composition, the same owner
26
+ plugin-owned presentation effect changes the nearest DSH scope. A non-empty `tools:ptc-only`
27
+ section proves `ptc`, an empty section proves `both`, and the preceding generation's
28
+ `tools:code-only` alias proves the same composition; the current section wins when both appear, and
29
+ only a missing owner signal permits a tool-shape inference. For a code composition, the same owner
29
30
  registers `edit_run_code` through `agent.ctx.tools.register()` and uses the same scope's
30
31
  `tools.presentAs('both')` to admit both direct calls. It retains both exact disposers and releases
31
32
  registration and presentation together with the owning session, agent, or plugin. Native-mode and unrelated agent
@@ -105,10 +106,10 @@ would repeat unrelated policy context. Rewrite feedback and unrelated recovery t
105
106
  own independently justified lifecycles.
106
107
 
107
108
  A live `PTC-C001` at the exact source EOF may carry a validated one-call repair. The analyzer tries
108
- only the three single-token suffixes `}`, `)`, and `]` against the same binding catalog, reserved
109
- bindings, redeclaration mode, rewrite policy, and import state as the rejected cell. Exactly one
110
- candidate must complete preparation without a binding collision, and the existing exact editor
111
- must be able to express it from a bounded unique source suffix. The rejected call must also have a
109
+ only the 12 suffixes of one or two closing tokens drawn from `}`, `)`, and `]` against the same
110
+ binding catalog, reserved bindings, redeclaration mode, rewrite policy, and import state as the
111
+ rejected cell. Exactly one candidate across both lengths must complete preparation without a binding
112
+ collision, and the existing exact editor must be able to express it from a bounded unique source suffix. The rejected call must also have a
112
113
  persistent event sequence. The diagnostic then renders those already-validated
113
114
  `edit_run_code({ edits: [...], expected_target_call_seq })` arguments on one help line. At dispatch,
114
115
  the precondition binds the proof to that rejected cell even if another matching source has become
@@ -6,11 +6,11 @@ PTC Plus needs a tracked instruction surface for product boundaries, source owne
6
6
 
7
7
  ## Decision
8
8
 
9
- `AGENTS.md` contains only obligations whose subject is PTC Plus: DSH authority, runtime and journal invariants, public source ownership, the checkout-local review ledger, deterministic verification, documentation parity, generated-material exclusions, and delivery safety. It links the canonical product and architecture documents rather than duplicating their detailed behavior.
9
+ `AGENTS.md` contains only obligations whose subject is PTC Plus: DSH authority, runtime and journal invariants, public source ownership, checkout-local review state, deterministic verification, documentation parity, generated-material exclusions, and delivery safety. It links the canonical product and architecture documents rather than duplicating their detailed behavior.
10
10
 
11
11
  Reusable maintenance methods remain outside tracked project sources. Local editor state and branch topology also remain checkout-owned. They may guide an individual maintainer, but project code, tests, hooks, and acceptance do not require their names, installation, or presence.
12
12
 
13
- The tracked ledger template and lifecycle script remain because they enforce a repository-specific commit invariant: unresolved findings cannot be committed, and a verified source tree must match the prospective Git tree. The tracked hook is limited to that invariant and is installed explicitly.
13
+ The tracked findings-ledger and review-plan templates and their lifecycle script remain because they enforce repository-specific commit invariants: unresolved findings cannot be committed, changed paths need declared semantic coverage, lane evidence follows dependency-scoped invalidation, and a verified source tree must match the prospective Git tree. The tracked hook is limited to those invariants and is installed explicitly.
14
14
 
15
15
  ## Alternatives considered
16
16
 
@@ -7,6 +7,13 @@ The persistent REPL contract must stay short enough for every request, while som
7
7
  ## Decision
8
8
 
9
9
  PTC-owned dynamic information uses independently sourced, accepted DSH messages.
10
+ All newly emitted PTC messages, including authoring instructions and binding-action
11
+ receipts, use `source.kind: 'plugin:ptc-plus'`, the producer identity assigned by
12
+ DSH's official source migration. They never emit the retired `kind: 'plugin'`
13
+ wrapper. Readers retain that historical wrapper and recognize current Host
14
+ `runtime-context` sources as well as historical system-prompt sources. Source
15
+ admission is tested through the official persistence codec; an in-memory Session
16
+ alone does not establish that a message can be saved or resumed.
10
17
  Unproved rewrite completion and Cordis recovery form a bounded `ptc-plus`
11
18
  `snapshot` with named sections. Configured Global User Binding documentation uses
12
19
  DSH's existing `catalog` form, independently of transient recovery state. A recovery tip is a `ptc-plus` `notice` whose
@@ -6,11 +6,11 @@ An ignored root `REVIEW_FINDINGS.md` prevents unresolved review findings from be
6
6
 
7
7
  ## Decision
8
8
 
9
- `.agents/templates/REVIEW_FINDINGS.md` is the tracked schema owner for local review ledgers. Schema `dsh-review-findings/v3` separates each finding's stable required outcome, current implementation plan, accumulated resolution evidence, and optional accepted-disposition owner. A finding can be captured before diagnosis produces a plan; once a concrete correction is selected, the plan is recorded before implementation and kept synchronized when evidence changes the diagnosis, ownership, affected artifacts, or verification path. `resolutionEvidence` records completed facts rather than a chronological work transcript. A finding marked `resolved` retains its implemented plan. A finding marked `accepted` names a tracked document or HTTPS issue in `dispositionRef`; the local ledger cannot be the only copy of an intentionally retained limitation.
9
+ `.agents/templates/REVIEW_FINDINGS.md` is the tracked schema owner for local review ledgers. Schema `dsh-review-findings/v3` separates each finding's stable required outcome, current implementation plan, accumulated resolution evidence, and optional accepted-disposition owner. A finding can be captured before diagnosis produces a plan; once a concrete correction is selected, the plan is recorded before implementation and kept synchronized when evidence changes the diagnosis, ownership, affected artifacts, or verification path. `resolutionEvidence` records completed facts rather than a chronological work transcript. A finding marked `resolved` retains its implemented plan. A finding marked `accepted` names a tracked document or HTTPS issue in `dispositionRef`; a local reference must be one exact tracked file that remains present in the source candidate, not a directory, pathspec match, or index entry deleted from the checkout. The local ledger cannot be the only copy of an intentionally retained limitation. The separate `.agents/templates/REVIEW_PLAN.json` owns the independent-review partition described by ADR 0026; a review plan routes verification work and invalidation, while the findings ledger owns discovered defects and their resolution.
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, 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.
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 the composite independent-review plan, lane verdicts, and final verdict defined by ADR 0026. Staging the complete verified tree permits repeated commit attempts; partial staging, additional staged content, mode-only changes, later checkout changes, uncovered paths, or invalidated lane dependencies require reconciliation before 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
 
@@ -40,4 +40,4 @@ Hook installation is explicit. `npm run hooks:install` selects the tracked hook
40
40
 
41
41
  ## Consequences
42
42
 
43
- Review findings have an explicit `reported -> authorized capture -> planned -> implemented and verified -> proof and archive -> matching commit -> proof retirement` lifecycle while retaining `open` and `resolved` as file-level states. An open ledger uses `verify` for deterministic evidence collection and fails `check` before its full gate runs; it also blocks commits. A resolved ledger remains active until verification succeeds against an unchanged source fingerprint, and commit readiness additionally requires the prospective index to match that fingerprint. The archive is intentionally local, while accepted limitations and durable architecture remain in tracked owners. Hook installation is an explicit checkout setup decision rather than a dependency-install side effect.
43
+ Review findings have an explicit `reported -> authorized capture -> planned -> implemented and verified -> proof and archive -> matching commit -> proof retirement` lifecycle while retaining `open` and `resolved` as file-level states. An open ledger uses `verify` for deterministic evidence collection and fails `check` before its full gate runs; it also blocks commits. A resolved ledger remains active until verification succeeds against an unchanged source fingerprint, and commit readiness additionally requires the prospective index to match that fingerprint. Independent review lanes have their own `plan -> parallel review -> dependency-scoped retry -> deterministic proof -> composite verdict` lifecycle and do not replace finding disposition. Both local records stay outside source history; accepted limitations and durable architecture remain in tracked owners. Hook installation is an explicit checkout setup decision rather than a dependency-install side effect.
@@ -8,17 +8,17 @@ Accepted
8
8
 
9
9
  ## Context
10
10
 
11
- PTC Plus 0.1.0 deliberately had no Client UI. The runtime surface was the DSH PTC mode `run_code`/`edit_run_code` transport, and adding a settings bundle was judged not to improve the core REPL path. The plugin also lacked a user-facing way to disable its runtime without removing the Cordis entry, and enabling/disabling state was invisible outside the session log. PTC Plus requires a plugin settings UI containing every Host Config field, a kill switch, and an explicit enabled marker. DSH's public settings service registers a namespace, the browser half contributes a card through `settings.plugin.item`, and the client receives the scoped settings service through `settingsScope`.
11
+ PTC Plus 0.1.0 deliberately had no Client UI. The runtime surface was the DSH PTC mode `run_code`/`edit_run_code` transport, and adding a settings bundle was judged not to improve the core REPL path. The plugin also lacked a user-facing way to disable its runtime without removing the Cordis entry, and enabling/disabling state was invisible outside the session log. PTC Plus requires a plugin settings UI containing every Host Config field, a kill switch, and an explicit enabled marker. DSH's public settings service registers a namespace; the browser half contributes a card through the generation's settings seat, and the client reads the installed generation's settings transport (`configForms` on the current alpha, `settingsScope` on the preceding RC).
12
12
 
13
13
  ## Decision
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'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.
17
+ The settings card belongs to plugin configuration. Current DSH renders a bundle's own configuration on the sidebar Plugins → Installed 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. Preceding Hosts use `settings.plugin.item` (keyed, root) in the Settings panel, keyed by the served namespace. `src/client-host-compat.js` publishes to these plugin configuration seats through `ctx.slots.inject`, which waits until the owning page declares its slot. General settings may coexist with plugin configuration and is not a seat for this 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 names the observed native plugin configuration seat. The package's top-level `icon` field points to a packaged SVG; DSH owns loading and displaying it on the installed bundle and row pages.
18
18
 
19
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
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.
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. On the generations that expose a section installer, 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. The newest settings generation exposes no section installer and serves only fields marked volatile in the plugin's exported `Config`; the Host provides the form and commits volatile-only changes into the live references, notifying the owning fiber through the public `loader/volatile-update` event. The plugin subscribes and reconciles through its existing update path instead of running a per-field settings watch. 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.
22
22
 
23
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.
24
24
 
@@ -24,6 +24,8 @@ Cordis tools remain native program bindings under `tools.*`. The PTC code-only d
24
24
 
25
25
  Cordis definitions and Runs are process-local, while PTC journals replay every settled program binding as a recorded value without redispatch. On the first prompt for an agent or a new Cordis enable generation, PTC Plus derives whether normalized journals contain a Cordis transcript. If they do, it emits the fixed `tools:ptc-plus-cordis-recovery` runtime context: recorded values remain journal data, but the model must perform a live read-only Cordis Inspect before relying on prior IDs, state, approvals, or capability observations. The context remains until a newly settled successful `cordis_inspect*` call appears in the session log. It neither asserts that live state was lost nor reruns a mutating call.
26
26
 
27
+ Companion Skill resolution is capability-based. The generations that discover presets from their composition directories publish an absolute composition path for the shipped `cordis` preset, and PTC Plus reads the sibling `skills` root. A generation that declares presets without publishing any composition path publishes no companion Skill root through `agentPresets` at all: PTC Plus reports that missing publication as an unsupported surface, naming the surface and its consequence rather than a shape failure of a healthy host, and keeps the existing rollback or single-warning withdrawal instead of assuming a directory. An unusable preset (`broken`) is reported as unavailable before any path shape is considered.
28
+
27
29
  ## Alternatives Considered
28
30
 
29
31
  1. Add the Cordis row to the PTC preset. Rejected: PTC Plus is installed as a host plugin and does not own or fork DSH's shipped preset files; a plugin setting keeps the optional mount within the plugin's ownership boundary.
@@ -28,12 +28,23 @@ artifact rewrite API when one exists. Until then, PTC Plus must not rewrite
28
28
  files obtained from private storage paths or race the persistence provider's
29
29
  append/flush queue. Legacy `ptc-plus/recovery-boundary` artifacts therefore
30
30
  remain an explicit, startup-before-restore migration concern rather than a
31
- runtime event handler concern.
31
+ runtime event handler concern. The dedicated retired-event converter accepts
32
+ only a Session format 0 artifact with a contiguous zero-based source identity graph, removes the retired events
33
+ and rewrites every supported Host and PTC sequence relation through one closed
34
+ old-to-new map. Before writing, it validates current-surface replacement and
35
+ compaction ranges, provenance, command and title sources, and complete
36
+ recovery-boundary application; invalid or unknown relations fail closed. If a
37
+ header records a seeded session, the converter also maps its exact inherited-
38
+ event cut across removed boundary events so child-owned events cannot become
39
+ inherited.
32
40
 
33
41
  Host format upgrades are also explicit pre-restore work. The migration CLI may
34
42
  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
43
+ conversion and current validation. When the selected catalog requires
44
+ parent-specific child evidence, the caller supplies the complete direct-child
45
+ facts or explicitly declares that the artifact has no children; the CLI does
46
+ not infer an empty child set. PTC result metadata remains opaque to that catalog.
47
+ The CLI therefore proves an ordered one-to-one relation between the
37
48
  unchanged tool records, remaps only PTC-owned sequence references, and validates
38
49
  the resulting timeline. Original call arguments and recorded effects are never
39
50
  rewritten or executed. Ambiguous records, invalid PTC evidence and mixed retired
@@ -6,7 +6,7 @@ Repeated project helpers are useful across sessions, but ordinary REPL bindings
6
6
 
7
7
  ## Decision
8
8
 
9
- Global User Bindings is an optional PTC Plus capability controlled by `userBindingsEnabled`, which defaults to `false`. Disabled mode does not read storage, inject values or new declarations, register management RPC or commands, or render management UI. The next permitted accepted step can withdraw a previously delivered declaration through the PTC binding catalog contract in [ADR 0010](0010-session-log-derived-recovery-tips.md). Enabling the capability does not change DSH authority, approval, scheduling, cancellation, sandbox, or the code-only direct-tool projection.
9
+ Global User Bindings is a PTC Plus capability controlled by `userBindingsEnabled`, which defaults to `true` so its management and authoring entry points are available on installation. An explicit `false` remains authoritative, including across upgrades; omission uses the current default. This feature switch does not change any saved entry's enabled state, create helpers, or save Agent drafts automatically. Disabled mode does not read storage, inject values or new declarations, register management RPC or commands, or render management UI. The next permitted accepted step can withdraw a previously delivered declaration through the PTC binding catalog contract in [ADR 0010](0010-session-log-derived-recovery-tips.md). Enabling the capability does not change DSH authority, approval, scheduling, cancellation, sandbox, or the code-only direct-tool projection.
10
10
 
11
11
  Each entry is a TypeScript module with named value exports, a stable ID, display/call name, `namespace` or `top-level` scope, selected symbols, purpose, enabled state, and optional `modelContext`. Omitted symbol selection derives every named value export; an explicit selection limits the exposed API. One strict normalizer derives body-free declarations, binding kinds and durability from source, fingerprints the complete stored entry, and rejects any supplied derivative that disagrees. Activated entries are ordinary writable REPL bindings; a model redeclaration follows the configured binding policy and shadows the default only for that session.
12
12
 
@@ -1,21 +1,37 @@
1
- # Persist the delivery verdict against the verified candidate
1
+ # Persist incremental review lanes against the verified candidate
2
2
 
3
3
  ## Problem
4
4
 
5
- A complete-tree independent review returns a sampled conclusion for one tree state. Nothing bound that conclusion to the candidate, so the same source bytes could be reported clean by one review and expose three reproducible defects to the next, and a clean verdict never stopped the following review from starting. The verification proof already bound `npm run check` to `{HEAD, fingerprint}`, but the review stayed a transcript outside the commit gate, and the gate allowed a commit whenever no proof, no ledger or only a historical clean review existed.
5
+ A single complete-tree independent review bound a clean conclusion to one tree, but every correction invalidated the whole conclusion. Earlier parallel reviews remained diagnostic transcripts even when a fix could not affect their owners, inputs, assumptions, or consumers. This forced repeated complete review, discouraged early parallelism, and allowed review boundaries to drift during execution without a machine-visible plan. Retaining every earlier conclusion without dependency information would be unsound for the opposite reason: a change to a shared owner can invalidate consumers whose own files did not change.
6
6
 
7
7
  ## Decision
8
8
 
9
- The delivery gate is a persisted verdict in checkout-local Git metadata (`review-findings/verdict`) holding `{schema, status, head, fingerprint, base, evidence}`. `status` is `clean`; `head` and `fingerprint` are the frozen candidate the independent complete review examined; `base` is the scope base commit and must be an ancestor of `HEAD`; `evidence` names the retained copy of the original review report and its SHA-256. `recordReviewVerdict` is the only writer: it requires both the `HEAD` and the fingerprint captured before the review, refuses a candidate where either changed, refuses any report whose last non-empty line is not `VERDICT: NO FINDINGS`, and copies the report into `review-findings/evidence` before hashing it. A report that is not clean retires the standing proof and verdict instead of leaving an earlier clean verdict in force. `preCommitReviewLedger` is fail-closed and requires a proof for the current `HEAD`, equal source and index fingerprints, and a clean verdict whose head, fingerprint and scope cover that candidate and whose evidence still hashes to the recorded value. An absent ledger, an absent proof or documentation-only work is not an exemption. A proof whose `HEAD` moved is retired together with its verdict, and a verdict that no longer matches the verified candidate is discarded without touching the proof; either case blocks the commit. The recording entry resolves the scope base to a full commit id, binds the current `HEAD`, and refuses a base that is not an ancestor of it, so a stored record cannot name a candidate other than the one under review. The bound values come from the `verified <head> <fingerprint>` line that `npm run check` prints and stores in the proof, and the independent report must stay outside the checkout or be ignored because the fingerprint covers untracked non-ignored paths.
9
+ Independent review starts from a checkout-local `REVIEW_PLAN.json`, created from `.agents/templates/REVIEW_PLAN.json` and recorded under Git metadata before reviewers run. This root file is the sole active plan source. Schema `dsh-review-plan/v1` declares obligations and semantic lanes. The five standard obligation IDs remain mandatory; a plan may add change-specific obligations but cannot replace the standard review surface. Each lane has a stable ID, scope, exact file or directory-prefix inputs, upstream lane dependencies, assigned obligations, owners, consumers, and discriminating counterexamples. Obligations are either covered by at least one lane or explicitly excluded with a non-applicability reason. Every path changed between the plan base and the current source tree must match at least one lane; the implementation never silently expands a lane to absorb an unplanned path.
10
+
11
+ The recorded plan resolves its base to a commit that is an ancestor of current `HEAD`. Before review state can use or record a clean conclusion, it parses the active file and compares its canonical hash with the recorded plan. Missing, malformed, or semantically different active content fails closed before an old clean conclusion can authorize delivery; JSON formatting alone is immaterial. Negative review disposition is fail-closed in the other direction: it can retire recorded authorization even while the active plan or current source has drifted. A revision reuses the recorded base unless a base is explicitly supplied. A lane fingerprint hashes the lane declaration, its persistent invalidation `{epoch, revision}`, the canonical Git mode and blob identity including raw pathname bytes of every current source-tree entry selected by that lane's path rules, and the fingerprints of all declared upstream lanes. Plan path rules match those raw bytes as UTF-8 encoded exact names or directory prefixes; diagnostics encode undecodable paths reversibly rather than confusing their identities. The dependency graph must be acyclic. A change to one lane's declaration, generation, or selected content changes that lane fingerprint and recursively changes every dependent fingerprint, while unrelated lanes retain their identity. Re-recording a revised plan preserves only lane verdicts whose base, lane identity, evidence identity, and resulting fingerprint still match; this makes a boundary revision explicit without discarding unrelated evidence.
12
+
13
+ Reviewers may run concurrently from the fingerprints printed by `review:plan` or `review:status`. `recordReviewLaneVerdict` retains the captured `HEAD` as provenance and accepts a clean report when the captured lane fingerprint still matches. An unrelated concurrent edit or `HEAD` advance therefore does not reject the report. A changed direct or upstream input does reject it. A report ending in findings or `VERDICT: INCOMPLETE` is inspected before current-candidate equality and retires that lane and its declared dependent closure from the recorded plan, not unrelated lanes. Temporary source or active-plan drift therefore cannot make rejected evidence effective again after restoring the earlier candidate. Each accepted report is copied under `review-findings/evidence`, hashed, and referenced by a `dsh-review-lane-verdict/v1` record whose internal lane ID and evidence name must match its declared lane and fingerprint.
14
+
15
+ Plan recording, lane verdict recording or retirement, aggregate finalization, clearing, and pre-commit authorization are serialized by one atomic repository-local lock under Git metadata. The lock records the owner PID and a unique release token and bounds acquisition; it never automatically reclaims an owner because no portable pathname operation can prove and remove that exact generation without an ABA race. Crash recovery is an explicit operator action after confirming no review-state command is active, scoped to the exact `review-findings/state.lock` path resolved by Git. A negative report ordered after an older clean recorder advances a persistent per-lane invalidation revision within a random epoch even if the lane is temporarily absent from the current plan, before retiring its current closure. Reaching `Number.MAX_SAFE_INTEGER` rotates to a different random epoch at revision zero, preserving both invalidation and future progress. The absent lane must already have a retained tuple; an unknown ID cannot create one, and every active lane requires an explicit tuple. The tuple is part of that lane's fingerprint and therefore every dependent fingerprint; reports captured before retirement cannot overwrite it after the lane is re-added. Generations survive normal clearing and lane removal. Missing, partial, or malformed generation state blocks authorization; clear preserves valid state but removes damaged state, and explicit plan reconstruction creates a new epoch so a damaged lifecycle cannot restore an older authorization identity. A new clean review captured after retirement remains valid. Status is diagnostic and need not hold the mutation lock. Because the active plan, source tree, index, proof, and evidence can also be changed outside these commands, finalization and pre-commit obtain a stable final observation of their relevant identities before persisting or returning authorization.
16
+
17
+ After all lanes are effective, `npm run check` produces the existing whole-source verification proof for current `{HEAD, fingerprint}`. `review:finalize` writes `dsh-review-verdict/v2`, containing that whole-tree identity, the base, the complete plan hash, and every effective lane fingerprint and evidence hash. The pre-commit hook separately requires an absent or terminal findings ledger, a proof for current `HEAD`, equal source and index fingerprints, complete changed-path coverage, an effective verdict for every lane, intact evidence, and a composite verdict exactly matching that plan and proof. Advancing `HEAD` retires the proof and aggregate verdict. Source or index drift makes both records ineffective while the mismatch remains; restoring their exact candidate identity makes them effective again, while accepting a changed candidate requires another deterministic proof and aggregate finalization. Lane evidence remains reusable when its semantic declaration, direct inputs, upstream fingerprints, base ancestry, and evidence hash still hold.
18
+
19
+ `REVIEW_FINDINGS.md`, `REVIEW_PLAN.json`, reports, lane records, plans, proofs, and aggregate verdicts remain checkout-local. The two root working files are installed into `.git/info/exclude`; reports must stay outside the checkout or be ignored. The old `dsh-review-verdict/v1` single-report format and `verdict` command are rejected rather than treated as composite evidence.
10
20
 
11
21
  ## Alternatives considered
12
22
 
13
- **Keep the review as an unpinned transcript.** Recording only that a clean review happened leaves the gate bypassable by editing after the review, by reusing a verdict for another candidate, or by deleting the metadata; the observed clean-then-three-defects sequence is exactly the failure it hides.
23
+ **Repeat one complete-tree review after every fix.** This binds review to exact bytes but discards unaffected independent evidence and serializes work that has explicit semantic boundaries.
24
+
25
+ **Partition only by changed file paths.** File ownership is mechanically convenient, but intrinsic handling, declaration publication, callable reconstruction, module contracts, and recovery cross file boundaries. Paths select fingerprint inputs; semantic scope, dependencies, owners, consumers, and counterexamples define what the reviewer must establish.
26
+
27
+ **Keep every clean lane unless one of its own files changes.** This misses shared-owner and contract changes. Upstream lane fingerprints enter dependent fingerprints so invalidation follows the declared semantic graph.
28
+
29
+ **Never permit plan changes after review starts.** A fixed incorrect boundary would preserve a known coverage gap. Plan revisions are allowed but versioned by content, must cover every changed path, and invalidate only lanes whose declarations or dependency inputs changed.
14
30
 
15
- **Let the gate pass when no proof or ledger exists.** This preserves the previous behaviour for small or documentation-only changes, but it also preserves the bypass: removing or archiving the metadata becomes a way to commit without any review.
31
+ **Automatically add uncovered paths to a nearby lane.** This avoids stopping the workflow, but a file path does not prove semantic ownership. The gate reports uncovered paths and requires an explicit plan revision.
16
32
 
17
- **Store the verdict inside the verification proof.** A single file is simpler, but `npm run check` runs before the review and must not require a verdict to exist; the two records have different producers and lifetimes, so the proof gains a verdict-identity check instead of the verdict's storage.
33
+ **Store lane evidence without a final whole-tree proof.** Lane fingerprints establish review inputs, not deterministic test success or exact prospective commit contents. The composite verdict therefore remains paired with `npm run check` and the index-tree gate.
18
34
 
19
35
  ## Consequences
20
36
 
21
- A clean verdict now binds one candidate and one report hash, so editing after the review invalidates the commit instead of silently passing. The cost is that every commit, including a documentation-only slice, needs a fresh `npm run check` and one complete independent review; the alternative is a gate that any metadata deletion bypasses. The hook cannot judge review quality: it proves that a clean report for these exact bytes was recorded, not that the review was complete, which is why the coverage matrix and the `VERDICT: INCOMPLETE` outcome live in AGENTS.md as review obligations.
37
+ Independent review can begin in parallel after focused checks, and a correction normally reruns only the failed lane and its dependency closure. A small change may use one lane, so partition overhead remains proportional to the work. The plan author must identify semantic dependencies accurately; automation proves declared coverage and evidence identity, not that the declarations are intellectually complete. A newly discovered dependency is a plan defect that must be recorded before review continues. Finalization still requires one stable-tree `npm run check`, but it no longer requires another reviewer to repeat every already effective lane.
@@ -16,6 +16,10 @@ Caller and helper environment boundaries are explicit. Each creation site projec
16
16
 
17
17
  The helper answers an on-demand utilization-sample request from its own loop, and `IsolatedWorker` exposes `sampleUtilization()`. `SessionCellExecutor` starts the wall bound at request submission, awaits that fresh baseline, then starts the compute interval before it posts the prepare or run frame, so work completed before submission is excluded while prepare blocking remains counted. The exception owned by [ADR 0024](0024-repl-console-observation.md) is a confirmed unfinished observation on the same worker: the executor may post prepare before starting budgets so the observation can finish, and the matching observation-completion/readiness acknowledgement starts them. A sample that times out, cannot be sent, disconnects, or exits is a bounded worker-exit failure: pending requests are cleared and no prepare/run frame is dispatched. The ready handshake still contributes an additional startup sample, but it is not the per-cell baseline and it does not reset or defer budgets.
18
18
 
19
+ Helper stdout and stderr are part of cell settlement, not unowned process noise. For every run, the Host chooses a nonce and arms one output round before posting source. The kernel writes nonce-bearing start markers to both native descriptors and waits for the Host to observe both before executing the cell. It writes matching end markers after evaluation, pending program calls and value encoding settle, but before posting `done`. The Host releases `done` only after both end markers arrive. Bytes between those fences, including direct fd 1/2 writes and inherited child stdio, belong to that physical run and share its aggregate output budget. Structured console logs retain their own order; stdout and stderr each retain pipe order, but the merged presentation does not claim a total chronology across the independent control and descriptor channels.
20
+
21
+ Bytes before a new start fence prove that a settled run still produced descriptor output, so the new run is rejected and the worker is reset rather than attaching those bytes to it. A structured console or stream callback keeps its scheduling execution identity through the worker's private async-local store; output after that execution closes sends a `late-output` control event and likewise rejects any affected run. Bare descriptor bytes carry no scheduling identity, so bytes that actually arrive between a later run's acknowledged start and end fences follow the physical-arrival rule instead of being attributed to an unknowable callback. Fence mismatch, overlap, excess output or out-of-round output is an explicit output-attribution failure and resets the transport. The first idle out-of-round chunk closes capture and starts reset immediately; when no request is active, the Host retains one failure for the next execution instead of continuing to drain an unbounded producer without a diagnostic.
22
+
19
23
  ## Alternatives considered
20
24
 
21
25
  **Keep the worker in the DSH process and only improve cooperative shutdown.** Asking user code to release its own realms cannot bound a wedged kernel, and any fallback in-host kill reaches the same upstream teardown path that ends DSH.
@@ -30,12 +30,23 @@ generation is.
30
30
  **Selection is a live capability.** The plugin's static injection names only the
31
31
  services both generations provide; the seam owner waits through `inject` for
32
32
  whichever execution service the host registers, in a scope that also requires the
33
- plugin's own services, and attaches once. When both are
34
- registered, the current generation wins, and the preceding generation attaches
35
- only when the current one is absent. Attachment runs in the injected scope, so
33
+ plugin's own services, and owns one live attachment at a time. When both are registered, the current
34
+ generation wins, including when it appears after a preceding-generation attachment.
35
+ That transition first disposes the legacy injected fiber and its complete effect
36
+ tree, then attaches in the current service's scope; cleanup from the retired scope
37
+ cannot clear the new owner. If that attach fails, the owner marks the current
38
+ service object unusable, re-arms the preceding-generation attachment
39
+ immediately, and reports the failure instead of leaving the plugin with no
40
+ execution seam; the failed object is never retried, while a replacement current
41
+ service supersedes the restored attachment. The preceding generation therefore
42
+ attaches only when the current one is absent or is the recorded unusable object.
43
+ Attachment runs in the injected scope, so
36
44
  the plugin is unloaded when the host unregisters that service and reattaches when
37
45
  it is registered again. A service that satisfies the name but not the contract
38
- (`run` or `resolve` missing) is reported as a load failure naming the service.
46
+ (`run` or `resolve` missing) follows the same path and is reported as a load
47
+ failure naming the service; when a preceding-generation attachment exists, the
48
+ report accompanies its restoration so `run_code` never silently returns to the
49
+ host provider.
39
50
 
40
51
  **Execution is one neutral call shape.** The owner publishes `invokeUpstream`,
41
52
  which reproduces each generation's own call shape — directly for
@@ -93,8 +104,17 @@ escalation it thinks it is offering.
93
104
  The plugin activates on both the current and the preceding host generation, and
94
105
  one test owner covers the selection rules, the neutral call shape, the descriptor
95
106
  takeover, and the release semantics for both. A host that registers neither
96
- execution service leaves the plugin waiting, exactly as a required injection did,
97
- rather than loading a plugin whose entry points can never run.
107
+ execution service cannot be served, and its activation settles with a bounded
108
+ diagnostic naming the missing seam — `no host execution seam (ptcRuntime or
109
+ codeRuntime) is registered` — after the attachment window instead of staying
110
+ pending: the host awaits loader settlement before it becomes usable, so an
111
+ unbounded wait would park every agent, native tool, and unrelated plugin rather
112
+ than failing this entry.
113
+
114
+ A current-generation service that fails to attach cannot leave the plugin
115
+ unattached while the preceding service is still registered: the preceding
116
+ attachment is restored and the failure is reported through the plugin's own
117
+ logger in addition to the injected fiber's activation result.
98
118
 
99
119
  `run_code` on the current host no longer advertises a per-call deadline or file
100
120
  sandbox, and DSH rejects those arguments with its own message instead of the
@@ -0,0 +1,29 @@
1
+ # Close semantic obligations by owner
2
+
3
+ ## Problem
4
+
5
+ Focused tests and coverage can prove their selected examples executed, but they cannot show that every plugin-owned semantic transformation or execution boundary has an owner, contract and independent oracle. Adding more examples to a single compiler or realm matrix leaves module, transport, recovery, host and client boundaries outside that matrix, while treating all Node behavior as one fidelity surface erases intentional PTC differences and bounded external assumptions. An unregistered source boundary therefore needs a deterministic failure before review, not a reviewer remembering to extend a list.
6
+
7
+ ## Decision
8
+
9
+ `semantic-obligations.json` is the tracked graph of plugin-owned semantic boundaries. Each obligation records one semantic owner, exact implementation files, disposition, owning contract, preserved observables or declared differences, execution entries, lifecycle states, language or data generations, platform bounds, consumers, oracle, executable evidence and upstream obligations. Dispositions distinguish behavior preserved from an external owner, intentional PTC differences and bounded external surfaces; an omitted or uncertain obligation is unknown and fails validation rather than being relabeled as preserved.
10
+
11
+ `scripts/semantic-obligations.mjs` validates the graph before build and coverage in `npm run verify`. The exact inventory covers every JavaScript implementation file in `internal/` and `src/`, the public `index.js` and `client.js` entries, and the journal migration entry, with exactly one semantic owner per file. Adding, removing or assigning a source twice fails closed until the graph changes. Contract and evidence files must exist, every obligation needs executable test evidence, dependencies must resolve without cycles, journal versions must remain a contiguous recorded range, and declared language and module generations must equal their executable owners. The command emits counts for preserved, intentional-difference, bounded-external and unknown obligations; zero unknown means closure over the declared plugin source boundary, not equivalence with all current or future Node or DSH behavior.
12
+
13
+ The graph complements, rather than replaces, focused tests, coverage and independent review lanes. A boundary-specific registry can enforce a stronger relation where the implementation supplies one: worker realm mutations use their classified installation entry and AST check, journal generations use their closed schema, and language/module generations use exported sets. Other records bind exact owner files and evidence so a new boundary cannot enter the tracked source inventory silently; review still evaluates whether an edit inside an existing owner changes its obligation or dependencies.
14
+
15
+ `docs/semantic-validation.md` explains how to choose an oracle and extend evidence. `REVIEW_PLAN.json` remains the checkout-local snapshot partition: its lanes may split or combine tracked obligations for review cost, but must preserve the graph's owner dependencies and changed-path coverage. A clean graph report establishes declared coverage only; deterministic verification and clean independent lane verdicts remain separate delivery requirements.
16
+
17
+ ## Alternatives considered
18
+
19
+ **Expand the Test262 or compiler matrix until it appears comprehensive.** Those matrices are strong independent oracles for selected language behavior, but they do not own worker transport, program bindings, journals, host integration or client projection and cannot detect an omitted entry outside their axes.
20
+
21
+ **Use line and function coverage as the global model.** Coverage shows code execution, not which observable must be preserved, whether a difference is contractual, or whether the expected value came from an independent source.
22
+
23
+ **Make the worker realm inventory the global registry.** Realm mutation is only one boundary. Folding compiler, module, wire, recovery and host behavior into Node surface rows would obscure their owners and recreate a manually sampled API matrix.
24
+
25
+ **Derive ownership only from each temporary review plan.** Review plans are candidate-specific and checkout-local. They cannot serve as the durable source inventory or contract graph required before a plan exists.
26
+
27
+ ## Consequences
28
+
29
+ New implementation files and generation changes require an explicit obligation update, and stale evidence blocks the normal gate early. The graph is intentionally bounded to plugin-owned JavaScript sources and declared platform contracts; dependency internals, arbitrary Node APIs and future DSH behavior remain outside the equivalence claim. Exact file assignment adds maintenance cost, but makes source growth and ownership movement reviewable instead of silent.
@@ -5,14 +5,14 @@ This directory records stable design constraints for PTC Plus. An ADR states a d
5
5
  ## Rules
6
6
 
7
7
  - **A new or changed durable decision updates or adds an ADR** in the same change. Record architecture, public or cross-module contracts, persisted or wire formats, and process or tooling choices that a maintainer may reasonably revisit. A difficult or non-trivial implementation of an existing decision does not by itself require an ADR.
8
- - **`## Alternatives considered` is mandatory.** Name each genuine alternative and why it lost, one bold-led paragraph per alternative. A decision recorded without what it beat invites re-litigation.
8
+ - **`## Alternatives considered` is mandatory for a new or changed ADR.** Name each genuine alternative and why it lost, one bold-led paragraph per alternative. A decision recorded without what it beat invites re-litigation. Entries written before this rule may use the shorter `## Alternatives` heading; repair them when they are next touched.
9
9
  - **Naming.** Files follow `NNNN-kebab-case-title.md`. Keep the number sequence monotonic; never reuse a number.
10
- - **Format.** One physical line per paragraph:
10
+ - **Format.** One physical line per paragraph in new entries, or the entry's own consistent wrapping when it already wraps; the headings and their order are what make an ADR readable:
11
11
  - `# <title>` — the decision in one line
12
- - `## Problem` — the motivation, written to stand without the solution
12
+ - `## Problem` or `## Context` — the motivation, written to stand without the solution
13
13
  - `## Decision` — shipped reality in the present tense; keep it current with what actually shipped
14
14
  - bespoke technical sections as needed
15
15
  - `## Alternatives considered` — mandatory
16
- - `## Consequences` — what the trade-off cost and bought
16
+ - `## Consequences` — what the trade-off cost and bought; older entries may carry `## Verification` instead or omit it
17
17
  - **Supersession.** When a later decision replaces an ADR, fold every unique rationale, alternative, and consequence into the current owner and repair inbound links before deleting the old file. Partial supersession keeps both files cross-linked. Git history is not the only copy of rationale.
18
18
  - **Kept current.** When the code later moves a file, renames a surface, or changes a default, update the owning ADR in the same change (facts only, not the decision itself).
@@ -42,7 +42,7 @@ DSH 为一个 agent composition 固定选择 `native`、`ptc` 或 `both`。首
42
42
  已执行或可能产生外部 effect 的目标,则必须依据操作 owner 的 retry/idempotence 契约和执行事实判断重跑。短 `run_code` 可以复用仍存活的 binding,但缩短源码不能证明幂等。能力和命令执行依赖当前 request
43
43
  与 execution world,模型必须先探查 live binding、实际 executable 和路径语义,不假设某个平台、shell 或 package runner。
44
44
 
45
- live `PTC-C001` 若精确落在源码 EOF,独立的 bounded analyzer 只把追加单个 `}`、`)`、`]` 的三个源码分别送入该 cell 提交时的同一 preparation context。仅当唯一候选通过、无 binding collision,现有 exact editor 能从不超过固定预算的唯一尾部物化同一源码,并且 runtime 已取得该 rejected `run_code` 的持久 call sequence 时,诊断才输出一行可直接调用的 `edit_run_code({ edits: [...], expected_target_call_seq })`。edit transport 把该 sequence 与其 call event 捕获的目标比较,目标已变化时不编辑也不派生执行。这项 validated repair 优先于长度阈值,但只证明语法/preflight 接受;插件不自动 dispatch,也不改写原始 `run_code`。非 EOF、多候选、多 token、超预算、缺少目标身份或后续 preparation 拒绝均使用 length-adaptive help。
45
+ live `PTC-C001` 若精确落在源码 EOF,独立的 bounded analyzer 只把追加由 `}`、`)`、`]` 组成、长度为一或二的 12 项候选源码分别送入该 cell 提交时的同一 preparation context。仅当唯一候选通过、无 binding collision,现有 exact editor 能从不超过固定预算的唯一尾部物化同一源码,并且 runtime 已取得该 rejected `run_code` 的持久 call sequence 时,诊断才输出一行可直接调用的 `edit_run_code({ edits: [...], expected_target_call_seq })`。edit transport 把该 sequence 与其 call event 捕获的目标比较,目标已变化时不编辑也不派生执行。这项 validated repair 优先于长度阈值,但只证明语法/preflight 接受;插件不自动 dispatch,也不改写原始 `run_code`。非 EOF、多候选、需要三个及以上闭合符、超预算、缺少目标身份或后续 preparation 拒绝均使用 length-adaptive help。
46
46
 
47
47
  稳定指引保留这些跨任务不变量和失败恢复的优先动作。长 cell 失败的短提示直接作为当前 `PTC-X001` 的结构化 `help` 输出;重复绑定失败和当前 execution world 中由诊断确认的 executable、shell 或 path 错误仍由当前 session log 派生为以 `tools:ptc-plus-tip/<trigger>/<ordinal>` 标识的独立 notice,词法失败指向可见源码与初始化,worker-owned capability 失败才指向能力探查,平台错误则提示重新确认环境。投影合并规范 PTC notice 与历史 DSH system-prompt snapshot sections,同一已投递 identity 跨两种来源只计一次,正文不参与身份判断。
48
48
  相同提示受 `tipCooldownMessages` 间隔约束,连续未解决时才升级为详细版本,成功 cell 会重置未解决计数;提示不会改变
@@ -52,11 +52,12 @@ system sections、tool schema 或 tool order,也不假设 Windows、WSL、POSI
52
52
 
53
53
  ## 设置与启用开关
54
54
 
55
- Host half 通过 DSH 公共 settings 服务注册 `ptc-plus` 命名空间,优先使用 provider-owned `installSection()`,并兼容根模块的 `installSettingsSection()`;两条路径共享同一 fallback、watch、rollback 与 disposal 语义。字段清单、默认值与校验来自 `internal/config-spec.js`。
56
- Client half 通过宿主当前代的设置座位呈现全部配置:旧代际是 `settings.plugin.item`(keyed,按 namespace),当前 DSH 是 Plugins 页面的 `plugins.row.config`(keyed,键 `<包名>#<行 id>`),两者由 `src/client-host-compat.js` 同一次发布、由声明槽位的一代渲染,页面按 `summary`/`page` 视图分别取一句描述与完整表单([ADR 0019](adr/0019-plugin-settings-and-kill-switch.md))。`enabled` 是 kill switch:关闭时保留 settings 注册、设置卡片与撤销旧 PTC 声明所需的被动 presentation cleanup;`enhancedToolView` 是默认开启的正文展示开关,关闭时只交还 DSH 原生 `run_code`/`edit_run_code` generic row,
55
+ Host half 通过 DSH 公共 settings 服务接入 `ptc-plus` 命名空间:提供 provider-owned `installSection()` 的代际直接注册,提供根模块 `installSettingsSection()` 的代际经兼容适配注册;两条路径共享同一 fallback、watch、rollback 与 disposal 语义。既不提供 section installer、又由宿主从插件导出的 `Config` 管理设置文档的代际(当前 alpha)被视为 host-owned surface:导出 schema 的全部字段带 volatile 标记,宿主据此提供表单并通过自身 config-editor 把 volatile-only 变更写入 retained handles;插件订阅宿主的 `loader/volatile-update` 事件,从同一 schema 重新解析 live 值并复用既有 reconcile、rollback 与 per-cell 配置代际语义。字段清单、默认值与校验来自 `internal/config-spec.js`。
56
+ Client half 在侧栏 **插件 → 已安装 → dsh-ptc-plus** 的插件行配置页呈现全部设置,通过 `plugins.row.config`(keyed,键 `<包名>#<行 id>`)注册;旧宿主的插件设置使用 `settings.plugin.item`(keyed,按 namespace)。`src/client-host-compat.js` 等待对应页面声明槽位,并按 `summary`/`page` 分别渲染一句描述与完整表单,不向通用设置注册。星光菜单在应用内弹窗复用完整表单与写入 owner;包元数据的 `icon` 指向随包发布的 SVG,由宿主显示在插件列表与详情页([ADR 0019](adr/0019-plugin-settings-and-kill-switch.md))。`enabled` 是 kill switch:关闭时保留 settings 注册、设置卡片与撤销旧 PTC 声明所需的被动 presentation cleanup;`enhancedToolView` 是默认开启的正文展示开关,关闭时只交还 DSH 原生 `run_code`/`edit_run_code` generic row,
57
57
  总开关关闭时不注册 runtime、执行 hook、tool surface 或 system prompt section,也不读取 binding 存储;`ptc` 与兼容 `code` preset 会话在头部单独显示 `PTC Plus` 指示器。设置卡片显示“已启用/已停用”,稳定指引不包含 UI 品牌名。
58
+ `Config` 的字段形态由 `internal/settings-compat.js` 按已安装代际的公共能力决定:仍提供 section installer 的代际保留普通描述字段,由自身文档路径提交校验后的具体默认值;只有自管设置文档的代际才加 volatile 标记,字段构建器不具备该能力的代际保持可加载。版本号不参与该判断。
58
59
  `autoDescribeRunCode` 默认开启且只控制请求绑定的本地执行策略。开启时,缺少外层 `run_code.description` 的调用使用派生参数通过本地 DSH 校验,备用摘要仅进入 presentation metadata;关闭时由 DSH 校验原始参数。两种状态的模型可见 tool schema、tool order 和 system sections 保持字节稳定并包含 required `description`;原始调用参数、cell 与嵌套 native 参数保持不变。
59
- 所有字段都由 settings watch 即时交给各自 owner,且不替换已有 session-bound binding。每个已提交 cell 固定其提交时的配置代际,timer、worker 消息、program binding bridge、结果校验和诊断共同消费该快照;重配置更新随后提交 cell 的默认值。`maxOldGenerationSizeMb` 在活动 worker 存在时因 Node 的创建期限制而拒绝并回滚。settings 服务缺失时 Host 回退到 composition config,并保持相同的运行时语义。
60
+ 在 section-installer 代际,所有字段都由 settings watch 即时交给各自 owner,且不替换已有 session-bound binding;在 host-owned 代际,宿主把 volatile-only 变更提交进导出 `Config` 的 retained handles,运行中的 fiber 经公开的 `loader/volatile-update` 事件就地 reconcile,同样保留已有 session-bound REPL、binding 与 journal。每个已提交 cell 固定其提交时的配置代际,timer、worker 消息、program binding bridge、结果校验和诊断共同消费该快照;重配置更新随后提交 cell 的默认值。`maxOldGenerationSizeMb` 在活动 worker 存在时因 Node 的创建期限制而拒绝并回滚。settings 服务缺失时 Host 回退到 composition config,并保持相同的运行时语义。
60
61
 
61
62
  `bindingUpdates` 是新配置的统一入口,默认 `stateful`,也可选择 `protected`。Host schema 保留该字段原始缺省状态,再由 `runtime-config.js` 把完整旧策略映射到相应新策略;混合旧开关保留显式 `legacyBindingSettings` 兼容态。Client 复用同一 resolver,仅在兼容态展示旧开关;用户选择统一开关时,一次 settings update 同时写入新策略并清除兼容标记。
62
63
 
@@ -103,7 +104,7 @@ Client 遇到冲突后重读 catalog、draft 和 review;只有权威空 draft
103
104
  | Replacement | 只有 DSH 拥有的 compaction 或其他显式 surface replacement 可以替换已保留历史;PTC Plus 不用 replacement 表达瞬时状态。 |
104
105
  | Independent request | 新的辅助模型调用必须单独说明 route、prefix 和 token 影响,不能用它的缓存表现证明主会话前缀稳定。当前插件不发起辅助模型请求。 |
105
106
 
106
- PTC 动态状态通过 DSH 公共 `agent/pre-step` 追加为 `source.plugin: ptc-plus` 的独立 `user/message`。未知完成状态的 rewrite feedback 与 Cordis recovery 构成有界 `snapshot`;全局绑定 API 说明使用独立 `catalog`;恢复 tip 是以 trigger/ordinal 为 identity 的 `notice`。恢复快照只替代 PTC 旧状态,空快照撤销旧状态,不替代绑定目录、authoring task、Skill、tool result 或其他 producer。PTC 更新不重发其他 owner 文本,其他 owner 的 aggregate 更新也不重发未变 PTC 信息。`systemPrompt.context` 中的空 witness 受 `includeRuntimeContext` 与 scoped suppression 管理且不渲染 aggregate 文本;assembly 捕获精确请求事实,pre-step 委托宿主 waterfall 后只对匹配且未取消的 accepted step 提议消息。已提交记录与公共 ordered surface 共同决定去重和状态重申;缺少公共 surface 时不推断可见状态,不投递。raw history 只可用于 tip identity/cooldown,不能让隐藏 binding 变成模型知识。关闭 PTC 后仅保留撤销旧声明所需的被动 presentation cleanup,不安装 runtime 或读取 binding 存储。Cordis 恢复使用规范 journal 与当前 agent/enable generation;绑定目录只描述当前启用配置,不要求激活证明。目录和恢复快照分别去重与撤销,Host aggregate 的撤销不适用于目录;暂停只限制新投递。历史快照中的绑定段由一次恢复快照退役。此类状态不得进入 `PromptAssembly.sections`,也不得通过 tool/schema/order 变化传递。来源、边界与历史兼容由 [ADR 0010](adr/0010-session-log-derived-recovery-tips.md) 拥有。
107
+ PTC 动态状态通过 DSH 公共 `agent/pre-step` 追加为 `source.kind: plugin:ptc-plus` 的独立 `user/message`。未知完成状态的 rewrite feedback 与 Cordis recovery 构成有界 `snapshot`;全局绑定 API 说明使用独立 `catalog`;恢复 tip 是以 trigger/ordinal 为 identity 的 `notice`。恢复快照只替代 PTC 旧状态,空快照撤销旧状态,不替代绑定目录、authoring task、Skill、tool result 或其他 producer。PTC 更新不重发其他 owner 文本,其他 owner 的 aggregate 更新也不重发未变 PTC 信息。`systemPrompt.context` 中的空 witness 受 `includeRuntimeContext` 与 scoped suppression 管理且不渲染 aggregate 文本;assembly 捕获精确请求事实,pre-step 委托宿主 waterfall 后只对匹配且未取消的 accepted step 提议消息。已提交记录与公共 ordered surface 共同决定去重和状态重申;缺少公共 surface 时不推断可见状态,不投递。raw history 只可用于 tip identity/cooldown,不能让隐藏 binding 变成模型知识。关闭 PTC 后仅保留撤销旧声明所需的被动 presentation cleanup,不安装 runtime 或读取 binding 存储。Cordis 恢复使用规范 journal 与当前 agent/enable generation;绑定目录只描述当前启用配置,不要求激活证明。目录和恢复快照分别去重与撤销,Host aggregate 的撤销不适用于目录;暂停只限制新投递。历史快照中的绑定段由一次恢复快照退役。此类状态不得进入 `PromptAssembly.sections`,也不得通过 tool/schema/order 变化传递。来源、边界与历史兼容由 [ADR 0010](adr/0010-session-log-derived-recovery-tips.md) 拥有。
107
108
 
108
109
  所有模型可见输入都必须能从 session log 重建。静态 system/schema 由 `request/header` 保存,动态 context 由带来源的 `user/message` 保存;进程内临时状态不能直接成为未记录的模型输入。在同一插件版本与配置下,普通执行结果、可编辑目标、诊断和其他插件拥有的运行期变化都不得改变 header;`edit_run_code` 的身份与结果由真实 call/result 表达,不生成 edit feedback context。插件升级、显式配置变化、provider/model route 变化、真实 native capability schema 变化,以及 DSH 拥有的 history replacement 可以使缓存从首个变化 token 起失效。
109
110
 
@@ -176,7 +176,7 @@ slot 的迟到、释放、再次声明和功能开关必须测试。缺少所需
176
176
  | 日志与请求 | 展示、展开、隐藏和历史查看不新增 event、模型提示词或声明,不影响前缀稳定性、journal 或模块初始化;真实保存沿用已有 notice/catalog 契约。 |
177
177
  | 能力生命周期 | 验证既有与当前契约、迟到声明、释放、重挂载和开关。能力缺失时保留紧凑请求与明确不可用提示,没有历史写操作或无效的打开入口;恢复后沿用候选和显隐选择。审批接管不误报能力缺失,不以版本号或新造 slot 代替能力证明。 |
178
178
 
179
- 按项目 ledger 流程记录实施发现,最终在稳定树上运行 `npm run check` 和 `git diff --check HEAD --`。独立 reviewer 无缺陷、确定性测试通过、实际 UI 验收是不同证据;不能把其中任一项替代其余。提交与发布仍遵循用户授权及独立审查条件。
179
+ 按项目 ledger 流程记录实施发现,按预先声明的独立 review lanes 取得各 lane 的有效 verdict,最终在稳定树上依次运行 `npm run check`、用 `npm run review:finalize` 记录 composite verdict,再运行 `git diff --check HEAD --`。独立审查、确定性测试、实际 UI 验收是不同证据;不能把其中任一项替代其余。提交与发布仍遵循用户授权及独立审查条件。
180
180
 
181
181
  ## 公共契约与历史证据
182
182
 
package/docs/client-ui.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Client UI
2
2
 
3
- PTC Plus 提供**插件设置卡片**。卡片座位由宿主代际决定:旧代际在 DSH Web/Desktop 的 Settings → Plugin configuration 中以 `settings.plugin.item` 渲染,当前 DSH 在侧栏 Plugins 页面以 `plugins.row.config`(键 `<包名>#<行 id>`)渲染该 bundle 自己的配置;`src/client-host-compat.js` 同时发布到两个座位,由声明了槽位的那一代决定哪个生效,卡片按座位提供的 `summary`/`page` 视图分别渲染一句描述与完整表单。输入框旁的星光菜单还直接打开复用同一表单的应用内设置窗口,不依赖宿主页面的局部导航状态;菜单项悬浮提示保留原生设置座位的路径。
3
+ PTC Plus 提供**插件设置卡片**。卡片座位由宿主代际决定:旧代际在 DSH Web/Desktop 的 Settings → Plugin configuration 中以 `settings.plugin.item` 渲染,当前代际在侧栏 Plugins → Installed 页面以 `plugins.row.config`(键 `<包名>#<行 id>`)渲染该 bundle 自己的配置;General 设置不是本卡片的座位,`src/client-host-compat.js` 只发布到这两个插件配置座位,由声明了槽位的那一代决定哪个生效,卡片按座位提供的 `summary`/`page` 视图分别渲染一句描述与完整表单。输入框旁的星光菜单还直接打开复用同一表单的应用内设置窗口,不依赖宿主页面的局部导航状态;菜单项悬浮提示保留原生设置座位的路径。
4
4
 
5
- Client 根入口只依赖 `settingsScope`、`slots`、`locale`、`connection` 和 `remote`。头部贡献直接消费公开 session slot 提供的 `useProjection`;REPL 注册另依赖 `sessions` 的当前选择和 projection face。命令卡片等待公开 command slot,composer 管理入口直接消费现有管理 Remote;其中的编写动作再等待 `remote.commands` 与公开输入 hooks,不依赖已改名的 conversation registry 或未使用的 `ui-session` 模块。缺失、卸载或迟到的 slot/provider 只影响需要它的贡献;没有 `useProjection` 时不挂载依赖它的会话视图,命令卡片保留宿主结果但不提供草稿操作。没有输入 hooks 时不显示编写动作,已有全局绑定仍可查看和启停。preset 优先读取 `agentPreset` projection,缺失时依次读取会话公开摘要里的 projection 值与旧宿主的 `agentPreset` 字段;binding 值和草稿资格不采用该回退。当前会话身份取宿主已发布的选中证据:旧代际在会话列表上投影 `current`,当前代际把视图选择留在 controller 之外、以主视图持有的会话表达。两者都不读取私有 store。设置和独立正文 tool view 继续可用,不读取私有 store 或自行重建会话状态。
5
+ Client 根入口只依赖 `slots`、`locale`、`connection` 和 `remote`;settings transport 由当前代的 `configForms` 或上一代的 `settingsScope` 可选注入提供。头部贡献直接消费公开 session slot 提供的 `useProjection`;REPL 注册另依赖 `sessions` 的当前选择和 projection face。命令卡片等待公开 command slot,composer 管理入口直接消费现有管理 Remote;其中的编写动作再等待 `remote.commands` 与公开输入 hooks,不依赖已改名的 conversation registry 或未使用的 `ui-session` 模块。缺失、卸载或迟到的 slot/provider 只影响需要它的贡献;没有 `useProjection` 时不挂载依赖它的会话视图,命令卡片保留宿主结果但不提供草稿操作。没有输入 hooks 时不显示编写动作,已有全局绑定仍可查看和启停。preset 优先读取 `agentPreset` projection,缺失时依次读取会话公开摘要里的 projection 值与旧宿主的 `agentPreset` 字段;binding 值和草稿资格不采用该回退。当前会话身份取宿主已发布的选中证据:旧代际在会话列表上投影 `current`,当前代际把视图选择留在 controller 之外、以主视图持有的会话表达。两者都不读取私有 store。设置和独立正文 tool view 继续可用,不读取私有 store 或自行重建会话状态。
6
6
 
7
7
  组件通过 renderer 提供的 `useProjection`、旧宿主的公开 `useSessions` 和注入 `hooks` 读取外部状态,设置写入与 RPC 由 apply 层注入 callback。业务组件不自行构造 external-store hook。设置、slot、provider 与插件释放共同拥有注册和订阅的生命周期;开关关闭时撤销相关贡献。
8
8
 
@@ -26,7 +26,7 @@ Host half 通过 DSH 公共 `settings` 服务注册命名空间 `ptc-plus`。字
26
26
  | REPL 语法 | `bindingUpdates` | 默认 `stateful`;同作用域的声明与赋值更新变量、函数、类和导入。选择 `protected` 后保护新建 const/import,并检测跨 cell 重声明。两种策略均支持静态 import/export。 |
27
27
  | 状态与恢复 | `durableReplay` / `tipsEnabled` | 默认开启;控制 worker 重启后的状态恢复与失败恢复提示。 |
28
28
  | 状态与恢复 | `tipCooldownMessages` / `tipEscalationFailures` | 同类提示间隔与详细提示阈值。 |
29
- | 工具扩展 | `userBindingsEnabled` | 默认关闭;开启后加载跨会话 TypeScript helper,并在开关下方显示管理按钮,同时启用全局绑定工作台与 `/binding` Agent 编写入口。 |
29
+ | 工具扩展 | `userBindingsEnabled` | 默认开启,显式关闭仍有效;开启时加载跨会话 TypeScript helper,并在开关下方显示管理按钮,同时启用全局绑定工作台与 `/binding` Agent 编写入口。 |
30
30
  | 工具扩展 | `cordisToolsEnabled` | 默认关闭;开启后为 PTC agent 加入官方 Cordis 工具、指引与精确的 `cordis-plugin-development` companion Skill,不发布同目录 sibling。 |
31
31
  | 界面显示 | `enhancedToolView` | 默认开启;关闭后注销 PTC Plus 的两个 keyed tool view,恢复 DSH 原生 generic row。 |
32
32
  | 界面显示 | `replViewEnabled` | 默认开启;控制顶级 REPL 页签,关闭时释放观察订阅,不影响设置中的全局管理入口。 |
@@ -34,7 +34,7 @@ Host half 通过 DSH 公共 `settings` 服务注册命名空间 `ptc-plus`。字
34
34
  | 资源限制 | `computeMs` / `maxWallMs` | 单 cell event-loop active(包括同步阻塞)与总耗时预算;前者不证明 CPU 消耗。 |
35
35
  | 资源限制 | `maxOldGenerationSizeMb` / `maxNestedRunCodeDepth` | kernel worker 内存与嵌套执行深度。 |
36
36
  | 资源限制 | `maxOutputBytes` | 单 cell 日志与返回结果的合计字节上限。 |
37
- | 资源限制 | `maxValueNodes` / `maxValueEdges` / `maxValueArrayLength` / `maxValueBigIntDigits` | Value Graph 与大数组、BigInt 的返回上限。 |
37
+ | 资源限制 | `maxValueNodes` / `maxValueEdges` / `maxValueArrayLength` / `maxValueBigIntDigits` | Value Graph 与大数组、BigInt 的返回上限;数组长度限制同时约束单数组和一份 graph 的累计槽位。 |
38
38
 
39
39
  旧配置的五个开关(`looseTopLevelRedeclarations`、`looseTopLevelFunctionClassRedeclarations`、`autoRewriteImports`、`autoStripExports`、`autoSplitRedeclarations`)先由共享 resolver 迁移。完整策略映射到 `stateful` 或 `protected`;混合选择保留显式兼容态,只有该状态才显示旧控件。兼容态的统一策略控件显示“沿用旧版设置(尚未迁移)”,可直接选择“允许重声明和覆盖”或“启用名称保护”;选择后一次写入同时保存 `bindingUpdates` 并清除兼容标记,随后执行和模型指引采用相同的新语言策略,设置页恢复统一开关。仅查看设置不触发写入。
40
40
 
@@ -81,6 +81,10 @@ PTC session 的头部弹窗在功能启用时增加 Session 与 Global 页签。
81
81
 
82
82
  `enhancedToolView` 默认开启并即时生效。开启时 PTC Plus 通过公共 keyed tool-view surface 为 `run_code` 与 `edit_run_code` 提供增强行,并在可用时使用 DSH 公共 `DisclosureRow`/`CodeBlock` primitive,缺少某项 capability 时使用插件自有的等价降级;关闭时立即注销这两个 keyed view,由 DSH 原生 generic row 负责布局、状态、代码高亮和输入/输出卡片。该开关只影响 Client 展示,不改变工具、prompt、runtime 或 session 语义。composer 星光入口使用公共 `Menu`、`Tooltip`、`Toast`、`Modal` 和 `IconSparkle16`;设置窗口复用设置卡片的完整表单与写入 callback,星光菜单的“修改绑定”第二步继续使用同一公共 `Menu` 的条目、滚动与键盘语义。缺失 `IconSparkle16` 时降级为纯文本按钮,缺失 `Toast` 时使用插件自有的内联状态提示;缺失 `Tooltip` 时悬浮说明由原生 `title` 承载。
83
83
 
84
+ 星光入口的四个动作(编写新绑定、修改绑定、管理全局绑定、PTC Plus 设置)始终由插件自己的动作区承载——`Agent 编写` 分组标题加两列网格,再一行工具入口——而不是宿主的列表行。该动作区优先放进公共 `Menu` 的 `children` 区域。这个区域不是所有已发布 Client 都会渲染的输入:较早的实现接受 `children` 属性却不挂载任何节点。`src/client-host-compat.js` 因此以已挂载输出而不是版本号判定该契约:首个 composer 入口挂载时渲染一次隐藏、非 portal 的 `Menu`,读取其中是否出现插件自己的哨兵子节点,随后在同一次提交内丢弃探测;答案在单个 Client 生命周期内只记录第一次结果,后续会话入口复用该答案、不再渲染探测。未渲染 `children` 时插件不把“未回答”当作结论,也不退化成宿主行:同一份动作区改由该 `Menu` 一向渲染的 pinned 区域承载(入口类型为 label,内容仍是插件自己的网格),因此分组、分组分隔线、两列布局、文案、顺序和设置座位提示在所有代际一致;渲染 `children` 的 Client 不再追加 pinned 副本,避免同一动作出现两次。pinned 载体只抵消自身的外边距和上边框,避免与宿主 footer 的 hairline 叠成两条;分组分隔线位于 `Agent 编写` 网格与工具入口之间,不会与它重复。已发布的 Client 至少渲染 pinned 区域;两处都不渲染的代际没有可承载这四个动作的宿主插槽,插件不以自有浮层替换宿主菜单,也不因此伪造宿主能力。探测挂载失败时不记录任何结论,入口保持原有渲染路径。
85
+
86
+ 悬浮窗里的条目启停不改变列表的可用性:写入由 catalog source 串行化、重复请求被丢弃,因此请求期间行不会被禁用(宿主会给禁用行降透明度)也不会插入“正在保存”行,避免整个悬浮窗在每次切换时闪一下;只有尚无目录可操作或读取失败时行才不可用。
87
+
84
88
  `autoDescribeRunCode` 的设置名称是“允许执行缺少摘要的 run_code”,默认开启并即时生效。缺少外层 `run_code.description` 时,调用使用派生参数通过本地 DSH 校验,备用摘要仅进入 presentation metadata;关闭时由 DSH 校验原始参数。两种状态的模型请求保持字节稳定并包含 required `description`,原始调用参数、已有摘要、cell 源码和嵌套 native 工具参数保持不变。
85
89
 
86
90
  设置卡片、正文 tool view 与 REPL 可复用 binding 卡片的全部文案都注册到 DSH client locale 的 `settings.ptcPlus` 命名空间,随当前界面语言在中文与 English 之间切换;字段名称与说明的两种语言文本同样来自 `internal/config-spec.js`(`label`/`labelEn`、`description`/`descriptionEn`,某一字段的说明要么两种语言都有,要么都没有),展示 chrome 文案由 client half 拥有。稳定 REPL 指引不承载 UI 品牌名。启用且会话选择 `ptc` 或兼容的 `code` preset 时,`conversation.session.header.actions` 以稳定 id `ptc-plus-active` 显示简洁的 `PTC Plus` 标识;视口不超过 560px 时隐藏该可选标识,为原生页头操作留出空间,会话绑定继续从 REPL 页签访问。preset 与 binding inventory 优先读取 session slot 的公共 `useProjection`;只有 preset 在缺少 projection 时可读取旧宿主公开会话摘要,binding inventory 不回退。关闭时不注入任何 PTC 指引或工具 surface。