dsh-ptc-plus 0.4.8 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +61 -123
- package/README.md +61 -123
- package/assets/dsh-ptc-plus-banner-en.webp +0 -0
- package/assets/dsh-ptc-plus-banner-zh.webp +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.cjs +42336 -0
- package/cordis.patch.yml +13 -2
- package/docs/README.md +7 -2
- package/docs/adr/0005-temporary-rejected-cell-edit-transport.md +31 -179
- package/docs/adr/0008-define-agent-operating-contract.md +5 -1
- package/docs/adr/0009-bound-expensive-acceptance-default.md +2 -2
- package/docs/adr/0016-archive-resolved-review-findings.md +1 -1
- package/docs/adr/0017-track-the-latest-dsh-public-surface.md +2 -2
- package/docs/adr/0019-plugin-settings-and-kill-switch.md +14 -3
- package/docs/adr/0020-optional-cordis-tools-in-ptc-mode.md +2 -2
- package/docs/adr/0022-stage-npm-releases-with-oidc.md +4 -2
- package/docs/adr/0023-global-user-bindings.md +3 -1
- package/docs/adr/0026-persist-the-delivery-verdict-against-the-verified-candidate.md +2 -0
- package/docs/adr/0028-attach-to-the-host-ptc-execution-seam.md +101 -35
- package/docs/adr/0030-serve-both-typert-codec-generations-from-one-codec.md +3 -3
- package/docs/adr/0031-close-semantic-obligations-by-owner.md +1 -1
- package/docs/adr/0032-own-session-log-facts-in-a-host-only-projection.md +27 -0
- package/docs/adr/0033-gate-client-visual-usability-in-a-browser.md +23 -0
- package/docs/adr/0034-keep-program-values-separate-from-output-projections.md +29 -0
- package/docs/adr/0035-run-coverage-only-before-a-new-release.md +27 -0
- package/docs/adr/0036-separate-focused-development-from-delivery-verification.md +29 -0
- package/docs/adr/0037-keep-tool-hover-previews-passive.md +52 -0
- package/docs/adr/0038-freeze-session-capability-plans.md +71 -0
- package/docs/adr/0039-verify-documentation-without-runtime-suites.md +29 -0
- package/docs/adr/0040-separate-capability-configurations-from-session-observations.md +39 -0
- package/docs/adr/0041-record-cell-execution-directories.md +65 -0
- package/docs/adr/0042-persist-provider-availability-and-handback.md +41 -0
- package/docs/adr/0043-compose-capability-and-context-policies.md +37 -0
- package/docs/adr/README.md +6 -0
- package/docs/architecture.md +25 -27
- package/docs/binding-review-placement-design.md +29 -21
- package/docs/capability-planning-components.md +93 -0
- package/docs/capability-projection.md +7 -0
- package/docs/client-ui.md +88 -29
- package/docs/client-visual-contract.md +65 -0
- package/docs/context-management.md +22 -0
- package/docs/context-optimization-plan.md +353 -0
- package/docs/context-public-interface-coverage.md +25 -0
- package/docs/durability-design.md +31 -14
- package/docs/evaluation.md +41 -6
- package/docs/evaluations/command-goat-deepseek-v4.1-flash-20261006.md +126 -0
- package/docs/evaluations/command-goat-deepseek-v4.1-flash.md +281 -0
- package/docs/installation.md +50 -8
- package/docs/program-data-plane.md +5 -3
- package/docs/publishing.md +5 -5
- package/docs/release-coverage.md +73 -0
- package/docs/release-notes.md +1 -1
- package/docs/review-procedure.md +56 -0
- package/docs/runtime-reference.md +48 -16
- package/docs/semantic-validation.md +14 -2
- package/docs/stateful-binding-updates-proposal.md +2 -2
- package/docs/user-bindings.en.md +2 -2
- package/docs/user-bindings.md +3 -3
- package/docs/value-wire.md +11 -1
- package/docs/verification-optimization-work.md +52 -15
- package/docs/verification.md +30 -86
- package/index.js +147 -23
- package/internal/binding-toggle-receipt.js +24 -0
- package/internal/capability-command-receipt.js +29 -0
- package/internal/capability-environment.js +1247 -0
- package/internal/capability-plan.js +285 -0
- package/internal/capability-policy.js +96 -0
- package/internal/capability-statistics-store.js +180 -0
- package/internal/capability-statistics.js +210 -0
- package/internal/compiler-platform.js +5 -3
- package/internal/compiler-service.js +2 -9
- package/internal/config-spec.js +79 -9
- package/internal/cordis-tools-owner.js +22 -19
- package/internal/direct-surface-owner.js +29 -29
- package/internal/dynamic-environment-runtime.js +9 -9
- package/internal/edit-transport-owner.js +183 -139
- package/internal/execution-provider-owner.js +160 -0
- package/internal/execution-seam-compat.js +76 -120
- package/internal/isolated-worker.js +12 -8
- package/internal/kernel-worker.js +104 -32
- package/internal/native-root-dynamic.js +12 -13
- package/internal/program-bindings.js +190 -0
- package/internal/recovery-tips.js +53 -23
- package/internal/rejected-cell-editor.js +8 -8
- package/internal/repl-observation-interest.js +11 -3
- package/internal/rpc-contract.js +1 -0
- package/internal/runtime-bridge-owner.js +351 -82
- package/internal/runtime-config.js +58 -0
- package/internal/runtime-contexts.js +85 -16
- package/internal/runtime-intrinsics.js +1 -0
- package/internal/runtime-messages.js +41 -0
- package/internal/sdk-projection.js +10 -82
- package/internal/session-cell-executor.js +42 -19
- package/internal/session-events.js +74 -4
- package/internal/session-journal-recovery.js +904 -184
- package/internal/session-journal-schema.js +6 -3
- package/internal/session-journal.js +31 -2
- package/internal/session-log-view.js +189 -43
- package/internal/session-runtime.js +175 -23
- package/internal/settings-compat.js +23 -6
- package/internal/stateful-module-compiler.js +3 -2
- package/internal/stateful-module-runtime.js +7 -3
- package/internal/stateful-root-runtime.js +9 -4
- package/internal/user-binding-authoring.js +2 -7
- package/internal/user-bindings-owner.js +47 -7
- package/internal/validated-parse-repair.js +1 -1
- package/internal/value-wire.js +68 -21
- package/internal/worker-cwd-virtualization.js +20 -18
- package/internal/worker-realm-surfaces.js +3 -3
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +55 -38
- package/src/client-authoring-view.js +286 -168
- package/src/client-binding-review.js +4 -1
- package/src/client-binding-toggle.js +18 -0
- package/src/client-capabilities-view.js +1341 -0
- package/src/client-capability-sort.js +29 -0
- package/src/client-code-editor.js +6 -0
- package/src/client-copy.js +881 -8
- package/src/client-feature-gates.js +15 -5
- package/src/client-host-compat.js +23 -2
- package/src/client-indicator-view.js +4 -6
- package/src/client-primitives.js +280 -0
- package/src/client-repl-view.js +23 -16
- package/src/client-settings-view.js +412 -69
- package/src/client-styles.js +193 -41
- package/src/client-tool-hover.js +185 -0
- package/src/client-tool-view.js +45 -11
- package/src/client-transport.js +44 -9
- package/src/client-workbench.js +9 -10
- package/src/client.js +148 -68
- 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/client.js +0 -31857
|
@@ -4,15 +4,15 @@
|
|
|
4
4
|
|
|
5
5
|
PTC Plus supplies the session-bound REPL by taking over the program-execution
|
|
6
6
|
seam DSH uses for `run_code`. DSH registers that seam as a Cordis service and
|
|
7
|
-
has renamed it between releases: the
|
|
8
|
-
`ctx.codeRuntime` (`@deepseek-ai/dsh-code-runtime`) and the
|
|
7
|
+
has renamed it between releases: the request-only contract publishes
|
|
8
|
+
`ctx.codeRuntime` (`@deepseek-ai/dsh-code-runtime`) and the resolved-spec contract publishes
|
|
9
9
|
`ctx.ptcRuntime` (`@deepseek-ai/dsh-ptc-runtime`). A plugin that declares the
|
|
10
|
-
|
|
10
|
+
absent name as a required injection never applies on that host. Cordis
|
|
11
11
|
does not fail such a plugin: the fiber stays pending, the plugin's entry points
|
|
12
12
|
are never registered, and `run_code` silently keeps executing in the host's own
|
|
13
13
|
runtime instead of the session REPL.
|
|
14
14
|
|
|
15
|
-
The
|
|
15
|
+
The resolved-spec seam also differs in more than its name. It resolves a request before
|
|
16
16
|
running it (`resolve(request)` → `run(spec)`), it publishes provider descriptors
|
|
17
17
|
(`executionInstructions`, `sandboxMode`, `timeout`) that gate host inputs, and it
|
|
18
18
|
reports file-confinement facts on the result. Its provider resolves a file policy
|
|
@@ -22,40 +22,75 @@ accepts a confinement request it cannot enforce silently weakens DSH's policy.
|
|
|
22
22
|
|
|
23
23
|
## Decision
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
`internal/execution-provider-owner.js` owns public provider composition;
|
|
26
|
+
`internal/execution-seam-compat.js` owns live selection and the request/spec
|
|
27
|
+
boundary. Selection uses the registered capability, not a version string.
|
|
28
|
+
|
|
29
|
+
**Composition owns the routing relationship.** The shipped bundle preserves the
|
|
30
|
+
original `ptc-runtime` row's module and configuration and gives its `ptcRuntime`
|
|
31
|
+
service a named isolation. A separate execution-provider row observes that
|
|
32
|
+
original entry through public Loader resolution and injection, then registers a
|
|
33
|
+
plugin-owned global provider through Cordis. The main plugin installs its
|
|
34
|
+
execution callback only in that provider's private entry. The original service
|
|
35
|
+
is never modified and may be frozen or sealed. Custom compositions configure
|
|
36
|
+
the original entry ID, service name and matching isolation explicitly. `codeRuntime` takes requests directly; `ptcRuntime` requires `resolve(request)` before `run(spec)`. The selected service contract, rather than release chronology, determines delegation. Entry IDs resolve in the
|
|
37
|
+
provider row’s owning Loader tree, including the profile’s Include subtree;
|
|
38
|
+
they are not assumed to be root-tree IDs.
|
|
39
|
+
|
|
40
|
+
The execution-provider row remains present when the main plugin is disabled;
|
|
41
|
+
without a callback it delegates native execution and capability getters to the
|
|
42
|
+
original. Its stable adapter follows original-generation replacement, but a
|
|
43
|
+
resolved spec remains bound to the generation that produced it and cannot run
|
|
44
|
+
after that generation retires. Before bundle removal changes the original isolation,
|
|
45
|
+
the public Loader lifecycle withdraws only the plugin's provider registration
|
|
46
|
+
synchronously, leaving the global service slot available for the original to
|
|
47
|
+
return. Cleanup cannot retire a newer registration. A plain, uncomposed provider
|
|
48
|
+
is a deployment error, not a reason to fall back to descriptor mutation.
|
|
49
|
+
|
|
50
|
+
Activation reads the current original generation's language through the live seam.
|
|
51
|
+
The adapter's stable identity does not make its first language a permanent fact;
|
|
52
|
+
an unsupported or unavailable current generation cannot authorize activation.
|
|
53
|
+
The original-generation observer also notifies the installed controller after source
|
|
54
|
+
replacement. An incompatible language retires the active PTC runtime without changing
|
|
55
|
+
the user's enabled setting; returning to TypeScript reconciles it again. Descriptor,
|
|
56
|
+
resolve/run and upstream delegation entries reject an installed-language mismatch
|
|
57
|
+
while that cleanup is pending, so SDK preparation cannot describe a different
|
|
58
|
+
language from the callback's execution. A TypeScript replacement retains the existing
|
|
59
|
+
session runtime. The subscription and its disposer belong to the injected controller.
|
|
29
60
|
|
|
30
61
|
**Selection is a live capability.** The plugin's static injection names only the
|
|
31
62
|
services both generations provide; the seam owner waits through `inject` for
|
|
32
63
|
whichever execution service the host registers, in a scope that also requires the
|
|
33
|
-
plugin's own services, and owns one live attachment at a time. When both are registered, the
|
|
34
|
-
|
|
64
|
+
plugin's own services, and owns one live attachment at a time. When both are registered, the resolved-spec
|
|
65
|
+
contract wins, including when it appears after a request-only attachment.
|
|
35
66
|
That transition first disposes the legacy injected fiber and its complete effect
|
|
36
|
-
tree, then attaches in the
|
|
37
|
-
cannot clear the new owner. If that attach fails, the owner marks the
|
|
38
|
-
service object unusable, re-arms the
|
|
67
|
+
tree, then attaches in the resolved-spec service's scope; cleanup from the retired scope
|
|
68
|
+
cannot clear the new owner. If that attach fails, the owner marks the resolved-spec
|
|
69
|
+
service object unusable, re-arms the request-only attachment
|
|
39
70
|
immediately, and reports the failure instead of leaving the plugin with no
|
|
40
|
-
execution seam; the failed object is never retried, while a replacement
|
|
41
|
-
service supersedes the restored attachment. The
|
|
42
|
-
attaches only when the
|
|
71
|
+
execution seam; the failed object is never retried, while a replacement resolved-spec
|
|
72
|
+
service supersedes the restored attachment. The request-only contract therefore
|
|
73
|
+
attaches only when the resolved-spec one is absent or is the recorded unusable object.
|
|
43
74
|
Attachment runs in the injected scope, so
|
|
44
75
|
the plugin is unloaded when the host unregisters that service and reattaches when
|
|
45
76
|
it is registered again. A service that satisfies the name but not the contract
|
|
46
77
|
(`run` or `resolve` missing) follows the same path and is reported as a load
|
|
47
|
-
failure naming the service; when a
|
|
78
|
+
failure naming the service; when a request-only attachment exists, the
|
|
48
79
|
report accompanies its restoration so `run_code` never silently returns to the
|
|
49
80
|
host provider.
|
|
50
81
|
|
|
51
|
-
**
|
|
82
|
+
**New requests and resolved execution specs remain distinct.** The owner publishes `invokeUpstream`,
|
|
52
83
|
which reproduces each generation's own call shape — directly for
|
|
53
84
|
`run(request)`, and as `run(resolve(request))` for the two-step seam — and
|
|
54
|
-
`
|
|
55
|
-
|
|
56
|
-
`
|
|
57
|
-
|
|
58
|
-
|
|
85
|
+
`installExecute(execute)`, which owns only the plugin provider's private callback
|
|
86
|
+
and returns its disposer. The plugin's entry receives the complete input.
|
|
87
|
+
`runUpstream(spec)` delegates an already resolved spec directly to the original
|
|
88
|
+
provider, retaining its object identity, cwd, deadline, sandbox policy and future
|
|
89
|
+
execution fields. Non-session callers use this path without resolving again.
|
|
90
|
+
Fresh isolated requests still use `invokeUpstream(request)`. Session cells consume
|
|
91
|
+
their program, bindings, signal and resolved cwd under the session's own execution contract;
|
|
92
|
+
[ADR 0041](0041-record-cell-execution-directories.md) records per-cell directory ownership;
|
|
93
|
+
the boundary never drops fields before choosing which consumer owns execution.
|
|
59
94
|
|
|
60
95
|
**The seam describes the execution the plugin performs.** While the plugin owns
|
|
61
96
|
the seam it also answers the descriptors with its own behavior: no
|
|
@@ -68,11 +103,33 @@ resolution, and sandbox escalation on those descriptors, so withholding them kee
|
|
|
68
103
|
DSH's authority decisions with DSH instead of accepting an input the plugin would
|
|
69
104
|
then ignore. Withdrawal is unconditional rather than generation-conditional,
|
|
70
105
|
because the rule belongs to the plugin's execution rather than to a generation:
|
|
71
|
-
the
|
|
72
|
-
its install closure reads them, so withdrawing there is inert
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
106
|
+
the request-only contract defines none of these members and nothing in
|
|
107
|
+
its install closure reads them, so withdrawing there is inert. These values are
|
|
108
|
+
derived getters on the plugin provider, not replacement descriptors on the
|
|
109
|
+
original. Releasing the private callback restores native delegation and its
|
|
110
|
+
original capability values without any write to the original service.
|
|
111
|
+
|
|
112
|
+
**The tool-result bridge has a separate accepted compatibility boundary.**
|
|
113
|
+
`internal/runtime-bridge-owner.js` retains its wrappers on the registered
|
|
114
|
+
`run_code` definition's `execute` and `output.presentationMeta`. The latter
|
|
115
|
+
publishes execution-local journal, recovery, binding and presentation evidence;
|
|
116
|
+
the former supplies derived execution arguments when an omitted description is
|
|
117
|
+
generated, while the persisted model-authored arguments remain unchanged.
|
|
118
|
+
This bounded use of a shared tool definition is accepted even though public
|
|
119
|
+
lookup does not guarantee mutation support. It requires those properties to be
|
|
120
|
+
redefinable: frozen definitions or outputs reject execution and are not a
|
|
121
|
+
supported compatibility claim. Frozen original execution providers remain
|
|
122
|
+
supported through the independent composition described above.
|
|
123
|
+
|
|
124
|
+
The bridge retains call-local settlement isolation, native canonical values,
|
|
125
|
+
output limits, original callback receivers, and descriptor/ownership restoration
|
|
126
|
+
on rollback or disposal. DSH continues to own validation, policy, approval,
|
|
127
|
+
cancellation and final result projection. Acceptance retains this bridge rather
|
|
128
|
+
than claiming that a public per-execution metadata carrier or raw/derived input
|
|
129
|
+
protocol has been implemented. Replacing it becomes necessary if an official
|
|
130
|
+
Host changes this dependency or publishes an equivalent result/input contract.
|
|
131
|
+
The direct-tool projection has its own accepted boundary in
|
|
132
|
+
[ADR 0005](0005-temporary-rejected-cell-edit-transport.md).
|
|
76
133
|
|
|
77
134
|
## Alternatives considered
|
|
78
135
|
|
|
@@ -90,8 +147,12 @@ plugin would publish a service it does not implement, making this a provider
|
|
|
90
147
|
rather than a consumer, and would have to model the wrapped provider's resolution
|
|
91
148
|
semantics for callers that never reach its REPL.
|
|
92
149
|
|
|
93
|
-
**
|
|
94
|
-
|
|
150
|
+
**Replace descriptors on the registered original.** Public service lookup does
|
|
151
|
+
not grant mutation ownership. Such attachment fails on frozen providers and
|
|
152
|
+
cannot establish a durable extension contract; it is not a compatibility fallback.
|
|
153
|
+
|
|
154
|
+
**Forward the resolved spec's deadline and policy to the session
|
|
155
|
+
kernel.** Current directory is integrated separately by ADR 0041. The kernel has its own budgets and journal semantics; a
|
|
95
156
|
per-call host deadline would have to be reconciled with the configured budget,
|
|
96
157
|
and confinement the plugin cannot enforce would be reported as if it applied.
|
|
97
158
|
|
|
@@ -101,9 +162,14 @@ escalation it thinks it is offering.
|
|
|
101
162
|
|
|
102
163
|
## Consequences
|
|
103
164
|
|
|
104
|
-
The
|
|
105
|
-
|
|
106
|
-
|
|
165
|
+
The default bundle and current official base profile use the `ptcRuntime`
|
|
166
|
+
resolve/run shape, also exercised by the frozen Host graphs. Explicit
|
|
167
|
+
`codeRuntime` request-only compositions retain public Loader fixture coverage
|
|
168
|
+
for request identity, replacement and bundle removal. The evidence boundary is
|
|
169
|
+
recorded in [Installation](../installation.md#compatibility-evidence).
|
|
170
|
+
Seam tests cover selection and input preservation for both shapes. Real public
|
|
171
|
+
Loader tests cover frozen originals, exact configuration and spec delegation,
|
|
172
|
+
main-plugin activation, source replacement and bundle removal. A host that registers neither
|
|
107
173
|
execution service cannot be served, and its activation settles with a bounded
|
|
108
174
|
diagnostic naming the missing seam — `no host execution seam (ptcRuntime or
|
|
109
175
|
codeRuntime) is registered` — after the attachment window instead of staying
|
|
@@ -111,8 +177,8 @@ pending: the host awaits loader settlement before it becomes usable, so an
|
|
|
111
177
|
unbounded wait would park every agent, native tool, and unrelated plugin rather
|
|
112
178
|
than failing this entry.
|
|
113
179
|
|
|
114
|
-
A
|
|
115
|
-
unattached while the
|
|
180
|
+
A resolved-spec service that fails to attach cannot leave the plugin
|
|
181
|
+
unattached while the request-only service is still registered: the request-only
|
|
116
182
|
attachment is restored and the failure is reported through the plugin's own
|
|
117
183
|
logger in addition to the injected fiber's activation result.
|
|
118
184
|
|
|
@@ -4,7 +4,7 @@ Date: 2026-09-18
|
|
|
4
4
|
|
|
5
5
|
## Problem
|
|
6
6
|
|
|
7
|
-
PTC Plus publishes its Remote services through DSH's TYPERT registry, and that registry validates every strict codec it is handed before any endpoint exists. The codec carries the decoder for one wire member, and DSH changed where the host reads it:
|
|
7
|
+
PTC Plus publishes its Remote services through DSH's TYPERT registry, and that registry validates every strict codec it is handed before any endpoint exists. The codec carries the decoder for one wire member, and DSH changed where the host reads it: a historical schema-based generation keeps the decoder on `codec.schema` and evaluates `codec.schema.parse(value)`, while the current generation keeps a `create()` factory, rejects a codec without it, and evaluates `codec.create().parse(value)`. The plugin published only the preceding shape, so a release that requires `create` fails registration inside the plugin's own activation: the Host entry never activates and the Client entry reports a failed fiber, although every import, load check, and type-level use still succeeds.
|
|
8
8
|
|
|
9
9
|
## Decision
|
|
10
10
|
|
|
@@ -12,7 +12,7 @@ PTC Plus publishes its Remote services through DSH's TYPERT registry, and that r
|
|
|
12
12
|
|
|
13
13
|
Each generation validates only the member it owns and ignores the other, so one published contract serves whichever shape the installed host implements. Compatibility follows the live acceptance behavior of the registry rather than a release version, and the decoder is published once, so a host that reads both members cannot obtain two different decoders for one wire member.
|
|
14
14
|
|
|
15
|
-
CI registers the packed contract with the installed host's own registry from the frozen official `latest` and `next` graphs (`scripts/dsh-rpc-contract-smoke.mjs`)
|
|
15
|
+
CI registers the packed contract with the installed host's own registry from the frozen official `latest` and `next` graphs (`scripts/dsh-rpc-contract-smoke.mjs`). Both frozen graphs read `create()`; they do not exercise a schema-only Host. Unit fixtures cover `schema.parse`, not a complete historical Host installation. The evidence boundary is [Installation: Compatibility Evidence](../installation.md#compatibility-evidence); passing two graphs must not be reported as packaging verification of both codec shapes.
|
|
16
16
|
|
|
17
17
|
## Alternatives Considered
|
|
18
18
|
|
|
@@ -24,4 +24,4 @@ CI registers the packed contract with the installed host's own registry from the
|
|
|
24
24
|
|
|
25
25
|
## Consequences
|
|
26
26
|
|
|
27
|
-
One plugin build
|
|
27
|
+
One plugin build carries both the historical schema-based and factory-based codec shapes, and the compatibility rule lives in a single module with the decoder published once. A future generation that requires another member, or that rejects a codec carrying a member it does not know, needs this owner updated; the regression test is CI's registration against the installed registry, which fails on the frozen Host graph that changed instead of on the user's machine. The decoder keeps the project's maintained schema runtime, so a host that validates payloads itself still evaluates the same semantics the plugin's own tests exercise through both members.
|
|
@@ -8,7 +8,7 @@ Focused tests and coverage can prove their selected examples executed, but they
|
|
|
8
8
|
|
|
9
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
10
|
|
|
11
|
-
`scripts/semantic-obligations.mjs` validates the graph before build and
|
|
11
|
+
`scripts/semantic-obligations.mjs` validates the graph before build and backend tests in `npm run verify`; release-only coverage scheduling is owned by [ADR 0035](0035-run-coverage-only-before-a-new-release.md). The exact inventory covers every JavaScript implementation file in `internal/` and `src/`, the public `index.js` and `client.cjs` 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
12
|
|
|
13
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
14
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Own session-log facts in a host-only projection
|
|
2
|
+
|
|
3
|
+
## Problem
|
|
4
|
+
|
|
5
|
+
Synchronous prompt consumers repeatedly folded the complete session log and separately scanned historical runtime snapshots and tips. Recovery also read an obsolete Session snapshot API, so removing that API could turn unavailable history into an apparently empty session. Independent caches at each consumer would retain duplicate semantic rules and cannot prove a common observation cut.
|
|
6
|
+
|
|
7
|
+
## Decision
|
|
8
|
+
|
|
9
|
+
`internal/session-journal-recovery.js` owns one synchronous event transition for the executable call/result timeline. Batch cold recovery and the host-only `ptcPlusSessionLog` projection use that same transition. The projection is registered through `sessionProjections` under its injected Cordis effect, has plain JSON state and an explicit state version, and publishes no Client wire view. Irrelevant log-only events return the previous reference.
|
|
10
|
+
|
|
11
|
+
The state preserves pending and ambiguous call identities, turn scope, edit-target claims, prune windows, normalized journals and transcript counts. It stores minimal call evidence and deterministic non-content result identity digests, not a second raw event log. Runtime presentation adds the ordered surface sequence vector and recognized runtime records. Replacement follows surface positions, not numeric sequence ranges: a newly appended replacement can occupy an earlier surface position. Historical notice identity, per-trigger ordinal, cooldown and unresolved escalation counts are updated at event entry; synchronous consumers read those facts without scanning the historical arrays.
|
|
12
|
+
|
|
13
|
+
Asynchronous consumers obtain an immutable cut from the public `sessionQuery.observeSession` reader, use `projectionMode: 'none'`, and release the observation lease. The captured cut is passed through recovery, call matching, no-op confirmation and derived edit execution. Its surface evidence is paired with that cut; a newer live surface cannot silently change an earlier observation. Historical array-backed sessions retain a read-only batch fallback over the shared transition. Missing current services or malformed historical arrays are diagnosed rather than represented as successful empty evidence. Cancellation and Host query failures remain authoritative errors.
|
|
14
|
+
|
|
15
|
+
The log-fact owner belongs to the plugin/controller lifecycle rather than an enabled worker activation. Disabling the runtime therefore leaves this host-only unit available to retract previously delivered PTC messages, while releasing tools, workers and enabled-generation UI projections. Unloading the plugin releases the unit. This does not keep hidden computation alive or inject a model-visible binding projection.
|
|
16
|
+
|
|
17
|
+
Result republication preserves the original settlement position and normalized evidence. A content-only prune clone, including a clone of another clone, is not a new execution, edit target, success or claim settlement. If the original result is absent, the original call position bounds the newly reconstructed chronology; later executions remain later. Tip identities retain their delivery positions so discovering an earlier success does not erase warnings delivered afterward.
|
|
18
|
+
|
|
19
|
+
Projection checkpoints are fold shortcuts only. State version 8 retains each settlement's independent publication index, first-observed index, ordinary/reconstructed classification and normalized run evidence, including ordinary runs without journals. Ordinary-result deduplication retains the first observation's call, event sequence and timeline position; admission requires matching ordinary settlement evidence or an identity-conflict clear, and every ordinary settlement requires its observation. It also retains the processed timeline position and ordered selection clears for turn resets and invalidations. The current frontier must agree with that retained lifecycle history and remain within the processed cut. Latest and editable runs are derived from the newest current-scope publication beyond that frontier; the success index is derived from retained successful publications. Edit targets and claim eligibility at dispatch are reconstructed from first-observed settlements and clears, using the same selection and target capture rules as the live transition. Their source must match the eligible ordinary or derived publication, and both current claim tables must match the reconstructed lifecycle. A late prune reconstruction cannot establish a target for an earlier dispatch. Selected fields and redundant target copies cannot certify their own provenance or chronology, and clones cannot revive a selection across an invalidation frontier. Normalized event facts retain call identity/source, result identity digests and formal source/replacement relations, public prune and turn inputs, journal presence, normalized settlement and recovery-boundary outcomes, and validated rewrites. They retain no result content. Checkpoint admission reconstructs the complete timeline with the same single-event transition used by live folding, then compares every materialized field. Journal/derived/binding facts, ordinary observations, settlements, selection, claims, transcript counters, unavailable evidence, pending/seen identities and the active prune window therefore share one lifecycle interpretation. Typed payload validation and the existing journal/derived/boundary owners validate the retained normalized inputs. The projection also retains presentation input facts: public append/replacement intents, context-step source categories and recognized runtime-message protocol inputs. Ordinary user and assistant content is omitted. These facts align with timeline event identity and drive the same projection transition at admission. The complete reconstructed projection must agree with the checkpoint, including ordered surface nodes, visible records/facts, message indexes, context steps and notice history. A historical catalog record therefore cannot certify its own visibility, and removing all visibility caches cannot suppress an actual append. Prompt consumers continue reading incremental state without raw-log scans. Missing settlements or valid-shaped journal divergences cannot be hidden by deleting their dependent caches. The timeline representation owner validates these relations together with typed table payloads, call/entry identities, normalized journals, derived runs and transcript counts before projection admission. Obsolete v1–v7 state requires refolding the complete log; a nonzero-start suffix alone is rejected with a seq-0 reread diagnostic. The Host owns watermark validation, suffix restore, fork inheritance and refolding. Raw journal ancestry and exact model-visible source relations still own recovery evidence. UI facts, cached state and matching recorded completions are not substitutes.
|
|
20
|
+
|
|
21
|
+
Submitting a cell reserves its memory configuration with the SessionRuntime owner before the first asynchronous observation on either the run or edit entry. The bridge and derived edit carry that same submission and its captured cut into execution rather than creating a second admission after reading. Runtime or session disposal invalidates that preparation, and an invalidated preparation cannot create a kernel or worker after the reader resumes. Reader failure releases the reservation; a genuinely new submission can use a fresh environment. Caller cancellation with an identified cut is settled by the existing cell owner as a no-op without starting a worker; it retains the caller's reason and does not create an unexplained recovery boundary.
|
|
22
|
+
|
|
23
|
+
## Consequences
|
|
24
|
+
|
|
25
|
+
pre-step and assembly read current projected facts rather than materializing history. Recovery and authoring receipt operations are explicit asynchronous reader consumers. Honest checkpoint restore and fork must preserve the same timeline, edit and runtime-message decisions as batch replay. Tests cover serialized transition boundaries, duplicate identities, prune replacement, observation/surface races, real SessionStore/query/registry composition and long unrelated histories.
|
|
26
|
+
|
|
27
|
+
This migration does not change tool names, journal generations, Host policy authority, output governance or the selected PTC language contract. Public execution-provider composition is owned by [ADR 0028](0028-attach-to-the-host-ptc-execution-seam.md), not this projection. Successful-result metadata and two-tool collapse integration remain separate boundaries.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Gate Client Visual Usability In A Browser
|
|
2
|
+
|
|
3
|
+
## Problem
|
|
4
|
+
|
|
5
|
+
JSDOM can verify component classes and callbacks while the browser paints unusable controls. Optional smoke scripts and saved screenshots leave key style regressions outside normal verification and provide no automatic verdict for focus or disabled feedback.
|
|
6
|
+
|
|
7
|
+
## Decision
|
|
8
|
+
|
|
9
|
+
The standard local and CI verification entries run one Client suite followed by deterministic browser layout and visual assertions against fresh actual-renderer fixtures. A shared bounded usability oracle owns contrast, action dimensions, reachability and state feedback. Fault counterexamples retain actual DOM classes and handlers and must be rejected. Browser prerequisites are explicit and absence fails verification. The coverage inventory and exceptions are owned by [the Client visual contract](../client-visual-contract.md).
|
|
10
|
+
|
|
11
|
+
Packed official-DSH acceptance remains a separate integration obligation under [ADR 0017](0017-track-the-latest-dsh-public-surface.md). It reuses the oracle on actual Host theme surfaces; fixture palettes do not establish Host compatibility. These checks do not change DSH authority, runtime state, program values or the model's tool surface.
|
|
12
|
+
|
|
13
|
+
## Alternatives considered
|
|
14
|
+
|
|
15
|
+
**Keep browser checks opt-in.** This permits a standard green gate while CSS is absent or state feedback is lost, which does not satisfy the Client usability obligation.
|
|
16
|
+
|
|
17
|
+
**Freeze full-page screenshot baselines.** Such baselines couple plugin acceptance to upstream typography and rendering pixels. Bounded computed-style and hit assertions directly test the product obligation, while screenshots remain useful diagnostics.
|
|
18
|
+
|
|
19
|
+
**Run every browser script independently in the gate.** The layout script would rerun the complete Client suite. Sharing a single fresh fixture generation preserves current-source evidence without that duplication.
|
|
20
|
+
|
|
21
|
+
## Consequences
|
|
22
|
+
|
|
23
|
+
Contributors need the locked Playwright Chromium installation before the full gate. Browser checks add work to verification and fail when their prerequisites are unavailable. Their guarantee is bounded by the declared controls and states; extending a UI responsibility requires extending its inventory and counterexamples rather than promising all future styles.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Keep program values separate from output projections
|
|
2
|
+
|
|
3
|
+
## Problem
|
|
4
|
+
|
|
5
|
+
An isolated PTC computation can return a value that the parent must continue computing with. DSH's outer execution seam accepts JSON-safe output, so its readable rendering of a BigInt or cyclic graph cannot also be the parent program result. An unsupported transfer likewise has different consequences before dispatch, after a binding completes, and after a cell computes its result.
|
|
6
|
+
|
|
7
|
+
## Decision
|
|
8
|
+
|
|
9
|
+
Plugin-owned isolated `code.run` uses the canonical completion of its settled child runtime, decoded by the existing PTC Value V1 codec. The child owns an independent binding root and is disposed after settlement. The private `runTentative` program-completion option validates canonical graph admission without generating model presentation; a sparse graph may fit transfer limits while its unused rendering would exceed them. Only the native execution seam consumes its public JSON-safe projection. An explicit `return undefined` has a `result` property; a child without a return does not. Existing native `run_code` members retain their owner-defined result contract, including when their execution re-enters the plugin. Legacy upstream execution retains its previous contract.
|
|
10
|
+
|
|
11
|
+
Journal calls already store canonical argument and result envelopes. Cold replay returns exactly the recorded value without redispatching child computation or external effects. Historical codec refusal diagnostics remain readable only when the actual refusal or a codec-owned legacy message exactly matches their recorded diagnostic; arbitrary errors do not acquire that compatibility. Historical strings remain strings; neither a language generation nor a wire migration is required because replay does not recompute the changed bridge result. Renderer text is never decoded or inspected to guess an encoding.
|
|
12
|
+
|
|
13
|
+
PTC Value V1 retains its explicit support domain. Codec-owned failures retain private structured categories (`unsupported`, `shape`, `budget`) and paths. Native Node brand checks identify known excluded data types without consulting user getters, `toJSON`, constructor names or `Symbol.toStringTag`. Prototype admission uses data descriptors; a hostile or unknown prototype remains unsupported. Proxy reflection in actual encoding still belongs to worker execution and budgets; diagnostic classification does not perform additional reflection.
|
|
14
|
+
|
|
15
|
+
Parameters reject before dispatch. Result encoding happens only after the owner call completes and reports that fact, possible effects and the absence of automatic retry. A completion encoding failure preserves the live worker and supplies category-specific help. Stable guidance distinguishes direct result transfer, live computation and native tool JSON contracts. Native JSON serialization and BigInt arithmetic retain their own errors.
|
|
16
|
+
|
|
17
|
+
## Alternatives considered
|
|
18
|
+
|
|
19
|
+
**Decode rendered strings.** Ordinary strings overlap with renderer output; parsing cannot recover value identity or distinguish a historical string from a canonical value.
|
|
20
|
+
|
|
21
|
+
**Return rich values through the public DSH seam.** The seam's JSON-safe contract does not permit this. A private canonical child completion already exists and provides the necessary boundary without changing Host packages or public dispatch.
|
|
22
|
+
|
|
23
|
+
**Expand V1 using structuredClone or Node v8 serialization.** Maintained platform serializers support more data types, but their semantics differ from V1: structured clone can read accessors, normalize class instances and descriptors, and v8 binary output does not provide this project's closed canonical JSON envelope and versioned admission guarantees. Type expansion requires a separately specified generation covering references, own properties, intrinsic state, budgets and historical decoding. Neither platform support nor a diagnostic repair proves those semantics. V1 is retained rather than silently widening or lossy-stringifying it.
|
|
24
|
+
|
|
25
|
+
**Convert BigInt to Number or JSON text automatically.** Conversion can lose precision or turn computation into string concatenation. Native tool schemas remain authoritative; callers select meaningful explicit representations at those boundaries.
|
|
26
|
+
|
|
27
|
+
## Consequences
|
|
28
|
+
|
|
29
|
+
Supported child values retain their types and graph relationships across plugin IPC, while parent and child bindings stay isolated. Unsupported live values remain usable inside their worker, with actionable transfer diagnostics instead of undifferentiated budget advice. This does not add support for Date, Map, class instances or live resources, or imply that a failed transfer undoes an external effect. The wire format, native owner authority and historical recorded results remain unchanged.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Run Coverage Only Before a New Release
|
|
2
|
+
|
|
3
|
+
## Problem
|
|
4
|
+
|
|
5
|
+
Collecting and merging instrumented coverage on every local verification and commit repeats release-readiness work during ordinary development. Behavioral verification, source-bound commit proof, and coverage thresholds establish different facts, so moving coverage must preserve the complete daily test suite and the independent-review gate.
|
|
6
|
+
|
|
7
|
+
## Decision
|
|
8
|
+
|
|
9
|
+
Coverage collection, coverage runner/report regression suites, and instrumented probes run only while preparing a new version for release. `npm run verify` and the `npm run check` proof path retain generated-build checks, syntax validation, Client verification, and the complete ordinary backend test suite without coverage instrumentation. Ordinary discovery selects root `test/*.test.js`; coverage-only suites and collection probes live under `test/coverage/`. The release coverage runner selects both inventories and owns `DSH_PTC_TEST_COVERAGE_SUITE=1` for mixed instrumented cases. Ordinary execution clears that marker. Both runners share the bounded concurrency calculation. Ordinary execution enables module mocks but does not preload coverage hooks or inherit coverage and temporary bytecode settings into the test process.
|
|
10
|
+
|
|
11
|
+
The Release workflow runs `npm run coverage` against its verified annotated tag before packing or npm staging. The full coverage gate retains compiler source remapping, plugin-source closure checks, 100% line and function coverage, and at least 95% branch coverage. A failure prevents staging. Normal CI keeps its portable runtime and official-Host contracts without collecting coverage. During release preparation, maintainers may run the full gate locally and use `npm run coverage:focus` to diagnose a failed coverage threshold; focused evidence cannot replace the full release gate.
|
|
12
|
+
|
|
13
|
+
This changes coverage scheduling, not findings-ledger readiness, independent review, source and index identity, or pre-commit authorization from [ADR 0016](0016-archive-resolved-review-findings.md) and [ADR 0026](0026-persist-the-delivery-verdict-against-the-verified-candidate.md). The release authority and immutable artifact path remain owned by [ADR 0022](0022-stage-npm-releases-with-oidc.md).
|
|
14
|
+
|
|
15
|
+
## Alternatives considered
|
|
16
|
+
|
|
17
|
+
**Keep coverage in every local verification and commit.** This preserves the old timing but forces development and review to pay the instrumentation and merge cost even when no new version is being prepared.
|
|
18
|
+
|
|
19
|
+
**Remove the coverage command without retaining the complete backend suite.** This shortens daily verification by silently dropping behavioral evidence. Ordinary verification instead retains every ordinary behavioral case while coverage-specific cases remain in the release inventory.
|
|
20
|
+
|
|
21
|
+
**Treat coverage regression fixtures as an exception to the daily prohibition.** Those test bodies can start collection or instrumentation even when the package command no longer invokes coverage. The scheduling boundary therefore owns test discovery and mixed-case selection as well as the top-level command.
|
|
22
|
+
|
|
23
|
+
**Require coverage only in a human release checklist.** This records the intended timing but lets the automated staging path publish a candidate without meeting the thresholds. The Release workflow enforces the gate before creating and staging the artifact.
|
|
24
|
+
|
|
25
|
+
## Consequences
|
|
26
|
+
|
|
27
|
+
Daily verification and commit proof no longer establish coverage thresholds. Those thresholds remain a new-version release requirement, and the release job needs enough time for the instrumented suite and report merge. Behavioral regressions still fail daily verification, while coverage deficits may first be discovered during release preparation. The maintained command and diagnostic contracts live in [release coverage](../release-coverage.md), [focused verification](../verification-optimization-work.md), and [publishing](../publishing.md).
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Separate Focused Development From Delivery Verification
|
|
2
|
+
|
|
3
|
+
## Problem
|
|
4
|
+
|
|
5
|
+
Requiring a complete deterministic gate after every executable development turn repeats long backend and browser matrices while the candidate is still changing. A focused command that silently defaults to all tests creates the same cost when an agent forgets a selection. Full behavioral validation and source-bound delivery proof remain necessary, but neither is a useful failure-localization loop.
|
|
6
|
+
|
|
7
|
+
## Decision
|
|
8
|
+
|
|
9
|
+
Development and independent review select the changed semantic owner and its bounded consumers. Executable edits alone do not trigger a complete gate. Backend and browser focused package entries require exact file or case selections before execution; listing the inventory is permitted without executing it. Client focused execution requires a test-name pattern. Independent layout diagnostics generate fresh HTML from only the two Client test owners that export all states. The complete visual gate retains the full Client suite once, followed by every layout and fallback case.
|
|
10
|
+
|
|
11
|
+
Complete validation runs on a stable executable candidate when preparing delivery/commit proof, when explicitly requested for full validation or timing, or when a specific cross-suite risk cannot be settled with focused evidence. [ADR 0039](0039-verify-documentation-without-runtime-suites.md) selects documentation checks for a strictly classified documentation-only delivery candidate. Use `verify` with unresolved findings and `check` otherwise. A valid result for an unchanged candidate is reused rather than repeating its component suites. A full failure returns to a discriminating focused check before the next stable-candidate gate.
|
|
12
|
+
|
|
13
|
+
These rules change scheduling, not test obligations, ordinary/release discovery, coverage thresholds, independent review, ledger readiness or pre-commit authorization. Focused evidence never becomes a commit proof. [ADR 0026](0026-persist-the-delivery-verdict-against-the-verified-candidate.md) retains the review/proof contract, [ADR 0033](0033-gate-client-visual-usability-in-a-browser.md) retains complete browser validation and [ADR 0035](0035-run-coverage-only-before-a-new-release.md) retains release-only coverage.
|
|
14
|
+
|
|
15
|
+
Runners expose inventory, concurrency and elapsed stage time. Agents wait on the existing process in intervals no longer than 60 seconds, remain responsive to new input, and inspect stage output when elapsed time exceeds expectations. A slow complete run does not authorize retries or a second concurrent copy.
|
|
16
|
+
|
|
17
|
+
## Alternatives considered
|
|
18
|
+
|
|
19
|
+
**Run a complete gate at the end of every development turn.** This makes turn boundaries, rather than candidate stability or delivery needs, determine expensive work and repeatedly verifies intermediate trees.
|
|
20
|
+
|
|
21
|
+
**Remove complete backend or browser cases.** This reduces time by weakening acceptance. Bounded concurrency, disjoint semantic partitions and eliminating duplicated fixture generation preserve the original obligations.
|
|
22
|
+
|
|
23
|
+
**Rely only on an instruction to choose focused tests.** A missing selector can still start the entire suite. Selection-required package entries reject that error before starting any tests or browsers.
|
|
24
|
+
|
|
25
|
+
**Treat focused success as delivery authorization.** This conflates selected behavioral evidence with complete validation and source/index identity. The final gate and pre-commit proof remain required for delivery.
|
|
26
|
+
|
|
27
|
+
## Consequences
|
|
28
|
+
|
|
29
|
+
Development results explicitly cover selected responsibilities. Cross-suite regressions may first appear at the stable-candidate gate or CI. Contributors must select relevant owners and consumers rather than claiming whole-tree correctness from samples. Maintained commands and examples live in [verification](../verification.md); the agent entry rules live in `AGENTS.md`.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# 0037 Keep Tool Hover Previews Passive
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
Execution rows occur inside the conversation's scrolling surface. A pointer can
|
|
10
|
+
cross a row because content moves beneath it. An interactive hover portal with
|
|
11
|
+
its own scrollbar then becomes the wheel target, changing the meaning of a
|
|
12
|
+
gesture already being used to browse the conversation. A longer delay alone
|
|
13
|
+
does not preserve scrolling once that portal opens.
|
|
14
|
+
|
|
15
|
+
## Decision
|
|
16
|
+
|
|
17
|
+
Execution-row hover is a passive quick peek. The plugin owns a compact preview
|
|
18
|
+
with bounded recorded source and result excerpts, explicit truncation text and
|
|
19
|
+
a hint to expand the row. Neither the preview nor its descendants participate
|
|
20
|
+
in pointer hit testing. Its layout uses clipping, not a scroll container. Full
|
|
21
|
+
source, result, Copy and Inspect remain in the explicitly expanded row.
|
|
22
|
+
|
|
23
|
+
`src/client-tool-hover.js` owns the lifecycle. A shared passive wheel/scroll
|
|
24
|
+
observer cancels pending and visible previews. Scrolling must be idle before a
|
|
25
|
+
fresh pointer movement or entry can start the next dwell; a stationary pointer
|
|
26
|
+
does not reopen a preview after scrolling. Keyboard focus is an explicit
|
|
27
|
+
request to preview. Escape, blur, pointer departure, expansion, touch and
|
|
28
|
+
unmount retain dismissal and original expansion semantics.
|
|
29
|
+
|
|
30
|
+
Use the platform's manual Popover top layer, with a public React Portal fallback.
|
|
31
|
+
Placement measures only the plugin's anchor, pointer and preview. Prefer the
|
|
32
|
+
right of the pointer when the current viewport has enough room; otherwise
|
|
33
|
+
place above or below the row. Observe live owned-anchor and viewport size changes.
|
|
34
|
+
A default-enabled interface setting controls mouse and keyboard preview without
|
|
35
|
+
removing explicit row expansion. The plugin does not
|
|
36
|
+
inspect or write Host ancestors, cancel scrolling, forward synthetic wheel
|
|
37
|
+
events, patch Host packages or add another authority boundary. The interactive
|
|
38
|
+
public HoverCard remains available to other consumers; it does not own this
|
|
39
|
+
passive tool preview.
|
|
40
|
+
|
|
41
|
+
## Consequences
|
|
42
|
+
|
|
43
|
+
Users see a short preview on deliberate hover and browse or copy full content
|
|
44
|
+
by expanding the row. Small viewports may clip more preview text or provide
|
|
45
|
+
insufficient room for a preview; the complete row remains available. Excerpts
|
|
46
|
+
are UI presentation and establish no claim about canonical value completeness,
|
|
47
|
+
model knowledge or state retention.
|
|
48
|
+
|
|
49
|
+
Browser evidence must use real wheel gestures over a scrollable conversation,
|
|
50
|
+
including pending preview, visible preview footprint and stationary-pointer
|
|
51
|
+
continuation. It must preserve keyboard/touch expansion and complete recorded
|
|
52
|
+
content. Theme and viewport checks cover both native Popover and Portal fallback.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# 0038 Keep Session Capability Plans Stable
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted and integrated through the public prompt and execution seams. Frozen plans, scoped execution projection, shared loaders, persistent family statistics, refresh, description recovery and result previews have focused executable evidence in the [public-interface coverage](../context-public-interface-coverage.md). This ADR does not claim demonstrated ordinary-task token savings; the [implementation plan](../context-optimization-plan.md) distinguishes deterministic implementation from paid task calibration.
|
|
6
|
+
|
|
7
|
+
## Problem
|
|
8
|
+
|
|
9
|
+
PTC Plus can improve continuous computation while increasing the context consumed to complete ordinary tasks. Retaining the full native SDK and adding discovery instructions does not itself provide progressive disclosure. Conversely, hiding descriptions without making capabilities discoverable can cause additional exploration or incorrect calls. Shorter individual requests therefore do not establish a useful optimization.
|
|
10
|
+
|
|
11
|
+
Capabilities also constitute the model's working environment. Redistributing them whenever statistics or saved settings change makes that environment unpredictable, even if each new distribution looks efficient in isolation. A capability advertised as removed must be absent from the supplied discovery and execution surfaces; a callable placeholder that rejects later does not establish that absence.
|
|
12
|
+
|
|
13
|
+
[ADR 0043](0043-compose-capability-and-context-policies.md) extends new environments with independent availability/disclosure rules, allocation inputs, collection, recovery and preview selections. The contracts below remain the historical v1/v2 recovery basis; freezing, authority and observation boundaries remain applicable.
|
|
14
|
+
|
|
15
|
+
## Decision
|
|
16
|
+
|
|
17
|
+
The managed domain is the task capabilities that DSH and its other plugins expose to the model, including tools, Skills and MCP resources or resource templates where public owner surfaces permit consistent integration. JavaScript/TypeScript, Node, the REPL, PTC Plus's own public APIs and Global User Bindings remain outside this management domain. DSH retains authorization, policy, dispatch and lifecycle ownership. The plugin uses published public extensions of the current official Host and does not create a parallel dispatch registry or patch Host packages.
|
|
18
|
+
|
|
19
|
+
Capability management has a total switch, independent statistics settings and independent manual configuration. There is no separate automatic/manual/off mode state. An explicit per-capability full, on-demand or closed selection wins over statistics. Invalid, disabled or unusable statistics leave manual configuration and its editable baseline effective. Automatic selection can choose full or on-demand disclosure; it cannot close a capability. Turning management off removes this feature's contribution while retaining DSH's authority and PTC Plus's separately configured computation behavior.
|
|
20
|
+
|
|
21
|
+
Full disclosure supplies the complete owner-defined calling contract. For a Skill it supplies the full catalog description, while the instruction body still loads on use according to the owner's model/user invocation eligibility. A user-only Skill remains configurable but advertises its user slash entry rather than the model loader. On-demand capabilities remain discoverable through bounded navigation and search, with matching full contracts preferably returned in one interaction. Closing a capability consistently removes its descriptions, discovery entries and applicable runtime exposure, including REPL members. Public integration gaps cannot be relabeled as successful closure or filled with a second permission system.
|
|
22
|
+
|
|
23
|
+
Automatic allocation uses session-family coverage rather than raw call volume. A root session and all its descendant agents contribute at most one use of a given capability. The denominator includes only families in which that capability was actually available. A tool use is a real call admitted to DSH’s around-execution pipeline with a final canonical outcome, including failed calls and valid wrapper-provided outcomes. It does not prove that the registered body ran or that an external effect occurred. Calls without execution admission and explicit pre-dispatch cancellation or unknown-tool outcomes do not create uses. Description inspection and cold replay do not create uses. Each capability and statistical scope uses its most recent configurable N eligible families, without wall-clock decay. Workspace evidence is primary; user-global evidence is a cold-start reference when local evidence is insufficient. An editable initial common set supplies the baseline when useful statistical evidence is absent, without fabricating observations.
|
|
24
|
+
|
|
25
|
+
Allocation considers both coverage and contract length within a configurable explanation budget. The directory has its own bound; every long-tail name need not remain in the prompt. Explicit full disclosure overrides the explanation budget, with an observable overage rather than silent truncation or demotion. A budget overage does not establish that a request fits a model's physical context limit.
|
|
26
|
+
|
|
27
|
+
A session capability plan records the effective enablement and disclosure choices when the session begins. Statistics and saved configuration do not redistribute an existing session, including after restoration. A user-triggered slash command explicitly refreshes the session. Refresh synchronizes descriptions, discovery and runtime exposure and supplies a durable, model-visible notification consistent with what actually became effective. A UI receipt alone is insufficient. Refresh uses Host lifecycle boundaries and does not require a paid model request merely to execute the human command. A stored plan cannot preserve a capability that its Host owner has actually removed or forbidden. Symmetrically, a live Host member that the frozen plan has not yet allocated remains declared under the Host's own presentation — or under its explicit availability closure — until refresh folds it into the plan; a pending allocation boundary never removes the member's identity from the declaration, discovery or dispatch surfaces. The frozen choice does not freeze the calling contract. Live parameter, output, instruction-dependency and Skill invocation changes append a validated `ptc-capability-contracts/v1` notification at an accepted step, retaining the original plan digest and current revision vector. Full choices receive complete replacement contracts; on-demand choices receive a revision notice and current discovery; removed capabilities receive a withdrawal. Saved settings and statistics still cannot reallocate that session. Unchanged views do not repeat notifications, and recovery uses visible validated notifications without rewriting the initial plan or prefix.
|
|
28
|
+
|
|
29
|
+
Explicit session choices and saved choices have separate owners. `/capabilities set session <encoded-id> <full|on-demand|closed|automatic|inherit>` changes only the current session. `automatic` explicitly removes that identity's saved manual override from the effective input; `inherit` removes its temporary override and resumes the adopted source choice. Ordinary `/capabilities refresh` adopts current saved configuration while retaining temporary choices. `/capabilities set global <encoded-id> <full|on-demand|closed|automatic>` saves through the public revision-checked settings writer and updates this session in the same Host maintenance operation, clearing only that identity's temporary choice. Other existing sessions remain frozen. Server choices allow only `closed`, `automatic` and session `inherit`; their closure precedes child choices, and reopening preserves children.
|
|
30
|
+
|
|
31
|
+
An initialized session publishes the complete new snapshot through its real append-only plan message. Before the protected system head exists, the formal `/capabilities` command returns its validated pending proposal in the structured receipt inside `CommandResult.text`; the Host alone records the paired `command/run` and successful `command/done`. These log-only command facts are not model knowledge. The first accepted step publishes that proposal to the model. Restoration reads successful receipts with exact command identity and raw input pairing, and plan messages, in order after the most recent explicit provider disablement; a routine provider release (`unloaded`) is an infrastructure fact and keeps the recorded plan as the session's restored baseline, so saved configuration still does not redistribute a resumed session. Restoration validates source/effective equality and the planner result, and does not repeat a global write, load a Skill body or execute a historical effect. Failed, cancelled, unpaired or damaged command facts cannot prove a choice; an unconfirmed live proposal is discarded before a later accepted step, and a late handler result cannot revive it. External plugins must not call `appendPluginRecord`, even though it is exported. History observations use the public `sessionQuery` cut; new production reads do not use deprecated synchronous Session readers.
|
|
32
|
+
|
|
33
|
+
All mutations use public `agent.runMaintenance`, which may reject a busy Agent. The plugin does not queue another session scheduler. Identity, inventory and management preflight precede a global write; the write uses the settings entry's actual namespace and revision. Global saving and session publication are different transactions: a saved choice remains saved if subsequent publication is refused or cancelled, while the old effective environment is retained and the receipt reports saved-but-not-applied. No automatic rollback overwrites a later settings writer. A committed operation followed by lost UI connectivity has an unknown UI outcome, so users inspect the actual plan before retrying. Target-specific read-only catalog commands include closed items for user re-enablement without publishing them to model discovery or counting them as use.
|
|
34
|
+
|
|
35
|
+
The existing prefix contract remains in force: unchanged configuration, model route and native capability view produce byte-stable plugin system text and ordered tool schemas. Statistical observations and session-plan facts belong in source-backed, reconstructable session contexts; treating a different plan as a new exception to prefix stability is not permitted. Reducing the original native SDK requires an owner-compatible public composition path, not a duplicate catalog appended beneath the unchanged full SDK.
|
|
36
|
+
|
|
37
|
+
Initial plans retain the v1 format. Explicit session choices use `ptc-capability-environment/v2`: `sourceSettings` is the adopted frozen saved configuration, `sessionOverrides` is the session-only input, and `settings` plus `plan` are validated derivatives. Plans are assembled before the first model request. Through the public accepted-step batch, the initial plan precedes task-dependent messages when no task history has been committed, after the Host-owned protected system head. Bounded navigation uses concise purpose guidance for available capability categories, rather than copying per-capability descriptions or selecting long-tail entries by identity and fit. It depends on configuration and inventory rather than automatic membership. Explicit full contracts precede selected baseline contracts and other automatic additions, with stable identity ordering and shared dependencies supplied once. Statistical counters and source digests do not enter rendered text. This extends reusable prefixes across different tasks and preserves earlier groups when statistics change; it does not promise provider cache hits. Full owner descriptions belong in full disclosure or requested discovery, not in the category directory. Existing sessions remain frozen, refresh and recovery append after retained history. Recovery validates the initial format, derived plan and exact rendered body. New snapshots record their navigation text; existing v1 snapshots without that field retain the previously emitted navigation contract.
|
|
38
|
+
|
|
39
|
+
After compaction, a separate bounded description-recovery operation may restore recently actually used, previously expanded and still-valid API descriptions. It deduplicates against the model-visible surface, does not redistribute the session plan and does not automatically restore Skill bodies. This is not authorization to add a default REPL state projection or weaken binding provenance requirements.
|
|
40
|
+
|
|
41
|
+
Large model-facing results and logs use bounded previews with retrieval of retained complete presentation content through existing Host facilities. Omission does not alter canonical program values or turn successful computation into failure, and retrieval does not rerun the original operation. Formatted retained text is not a substitute for canonical typed values.
|
|
42
|
+
|
|
43
|
+
The acceptance target is non-regressing quality and lower complete-task token consumption than native PTC with PTC Plus disabled on representative ordinary tasks. Accounting includes actual descendant agents, exploration, retries and all observable model requests, with cached input, uncached input and output reported separately. Missing usage remains unknown. Plugin-specific success, fewer prompt bytes and a higher cache-hit rate cannot substitute for this target.
|
|
44
|
+
|
|
45
|
+
MCP management has two levels. A `mcpServers.<server>: closed` manual control disables that server's tools and resource access before per-member disclosure choices are applied. Removing the server control restores the saved per-tool selections; it does not rewrite them. Membership is captured from the public MCP server directory or attributed MCP sections and the registered qualified tool namespace, and recorded as optional `mcpServer` evidence in the frozen inventory. Ambiguous namespaces cannot be closed by guessing an owner. Previously recorded inventories without this field retain their original per-member semantics. Server controls are configuration identities, not callable capabilities or new tool schemas. Settings can observe the Host's unprojected prompt sections through a plugin-defined public assembly context that bypasses PTC session preparation; observation neither freezes a plan nor loads binding inputs. Saving either level retains the existing new-session/explicit-refresh boundary.
|
|
46
|
+
|
|
47
|
+
## Alternatives considered
|
|
48
|
+
|
|
49
|
+
**Keep the full SDK and add more discovery guidance.** This preserves easy direct access, but adds an explanation path without removing the original context cost. Current discovery remains a useful implementation input; its existence is not evidence of progressive disclosure or savings.
|
|
50
|
+
|
|
51
|
+
**Make every capability on demand.** This minimizes the initial catalog but can force repeated discovery for common work. A bounded common set with manual overrides and measured coverage addresses both initial cost and later interaction cost.
|
|
52
|
+
|
|
53
|
+
**Continuously redistribute active sessions.** Reacting immediately to statistics or saved settings makes allocation current, but changes the environment beneath ongoing computation and harms prefix stability. New-session planning plus explicit refresh and deliberately scoped human choices preserves predictability.
|
|
54
|
+
|
|
55
|
+
**Expose three mutually exclusive management modes.** Automatic, manual and off outcomes are already derived from the total switch, statistics and manual settings. Persisting another mode introduces redundant state and obscures the independent validity of manual configuration.
|
|
56
|
+
|
|
57
|
+
**Hide descriptions and reject later calls.** This leaves the execution environment inconsistent with the advertised absence and adds a policy layer that DSH already owns. Closure requires removal from the supplied surfaces.
|
|
58
|
+
|
|
59
|
+
**Rank raw calls globally with time decay.** Repeated calls and large agent families can dominate the ranking, project differences disappear, and an idle project loses its baseline without new evidence. Bounded family contributions, workspace-first scopes and eligible-family windows address those specific distortions; they do not claim to measure latent task demand without bias.
|
|
60
|
+
|
|
61
|
+
**Restore every expanded contract or Skill after compaction.** This can recreate the context growth that compaction removed. Budgeted recovery of actual recent API use retains useful instructions while leaving other descriptions and Skill bodies on demand.
|
|
62
|
+
|
|
63
|
+
**Lower execution-output limits to constrain prompts.** An execution or transport failure has different consequences from a presentation omission. Separate preview budgets preserve computation and retrieval semantics.
|
|
64
|
+
|
|
65
|
+
**Conflate temporary choices with saved configuration.** It leaks one session's intent to new sessions and named configuration exports. Separate source settings and explicit temporary inputs preserve scope and reconstructable allocation.
|
|
66
|
+
|
|
67
|
+
## Consequences
|
|
68
|
+
|
|
69
|
+
The model receives a more predictable environment and users can inspect and override allocation. Implementation must jointly prove presentation, discovery, execution, refresh and restoration behavior rather than treating prompt editing as sufficient. Skills, shared MCP loaders, scoped tool registrations and retained runtime references require explicit public-surface evidence before complete coverage can be claimed.
|
|
70
|
+
|
|
71
|
+
Statistics require durable identity, bounded family accounting and a usable fallback. The [component contracts](../capability-planning-components.md) define family settlement and capability revision handling; `/capabilities refresh` implements the explicit session transition, with evidence in the [public-interface coverage](../context-public-interface-coverage.md). Contract budgets and discovery can themselves affect observed usage, so calibration must measure quality and whole-task cost rather than optimize coverage scores alone. Default parameters still require ordinary-task calibration; no unmeasured numeric default is established by this ADR.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Verify documentation without runtime suites
|
|
2
|
+
|
|
3
|
+
## Problem
|
|
4
|
+
|
|
5
|
+
A document-only commit previously ran every backend and browser test to obtain its source-bound proof. Those suites cannot establish whether prose, links or contributor instructions are correct, and unrelated environment failures can block a documentation correction. Moving procedures out of the default agent entry also has little benefit if every verification action reloads review coordination and release instrumentation details.
|
|
6
|
+
|
|
7
|
+
## Decision
|
|
8
|
+
|
|
9
|
+
`check` compares the complete source inventory against HEAD, including additions, deletions, untracked source files and Git modes. Only regular non-executable Markdown changes under `docs/` or in the four root documents `AGENTS.md`, `CONTEXT.md`, `README.md` and `README.en.md` select documentation verification. Every other change, an unborn HEAD or an unchanged candidate selects full verification. Templates and test fixtures are executable inputs to their consumers and are not classified by their Markdown extension alone.
|
|
10
|
+
|
|
11
|
+
Documentation verification checks diff whitespace, local link target existence and literal npm script references in changed documents and their referrers. It does not execute examples or contact external services. Independent review establishes semantic accuracy, instruction routing and heading-anchor correctness. `verify:docs` exposes this path for development and rejects a mixed candidate before launching any runtime suite. `verify` continues to request full behavioral validation explicitly; `check --full` requests full validation with a source proof even for documentation changes.
|
|
12
|
+
|
|
13
|
+
Both `check` branches retain ledger readiness and source/`HEAD` stability, but `check` does not enforce independent review or staged-tree identity. `review:finalize` enforces the recorded independent review plan and lane evidence after the proof exists, and pre-commit enforces exact prospective-index identity against the staged tree. The verification proof records the chosen scope as `documentation` or `full`; a documentation proof makes no claim about runtime test success. Existing proof identity and review invalidation rules remain in [ADR 0026](0026-persist-the-delivery-verdict-against-the-verified-candidate.md). This changes the documentation delivery branch of [ADR 0036](0036-separate-focused-development-from-delivery-verification.md); executable changes retain the complete delivery gate.
|
|
14
|
+
|
|
15
|
+
The default agent entry routes verification selection to `docs/verification.md`, review-state actions to `docs/review-procedure.md`, and release coverage to `docs/release-coverage.md`. Applicable requirements stay mandatory at their action boundary. Old verification section links remain as short forwarding sections. Test descriptions state the operation and observed contract; exact APIs, source fixtures, diagnostics and security properties remain accurate.
|
|
16
|
+
|
|
17
|
+
## Alternatives considered
|
|
18
|
+
|
|
19
|
+
**Run all runtime suites for every document change.** This spends time on an unchanged implementation while leaving documentation correctness to the same review still needed afterward.
|
|
20
|
+
|
|
21
|
+
**Permit manual hook skipping for documentation.** An exception can finish one commit but supplies no durable classification, source proof or repeatable validation path. The scoped check preserves those checks without requiring another exception.
|
|
22
|
+
|
|
23
|
+
**Classify every Markdown file as documentation, or inspect only the staged diff.** Test fixtures, templates, modes and unstaged source changes can affect executable behavior. The complete source inventory and explicit path boundary keep these changes on full verification.
|
|
24
|
+
|
|
25
|
+
**Automatically treat all test-name and comment edits as documentation.** Names participate in selectors and fixture exports, and source-looking comments or strings may themselves be test inputs. Development uses focused evidence; test-file changes retain full delivery verification.
|
|
26
|
+
|
|
27
|
+
## Consequences
|
|
28
|
+
|
|
29
|
+
Documentation delivery no longer depends on browser, runtime or cross-platform evaluation prerequisites. The checker proves mechanical references only; reviewers still need the affected contract owners. Executable changes can still expose cross-suite failures at the final gate. Reference routing reduces default reading without changing who owns a requirement, and does not establish provider acceptance rates or actual model-token savings.
|