dsh-vision-router 2.2.8 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/README.md +16 -7
  2. package/README.zh.md +16 -7
  3. package/docs/architecture/2.3.0-compat-retirement.md +147 -0
  4. package/docs/architecture/2.3.0-execution-plan.md +410 -0
  5. package/docs/architecture/2.3.0-final-audit.md +279 -0
  6. package/docs/architecture/2.3.0-reopened-plan.md +720 -0
  7. package/docs/architecture/3.0-architecture-plan.md +252 -0
  8. package/docs/architecture/3.0-r0-contract-ledger.md +137 -0
  9. package/docs/architecture/3.0-r1-source-artifact-boundary.md +98 -0
  10. package/docs/architecture/3.0-r10-final-correctness-closure.md +207 -0
  11. package/docs/architecture/3.0-r11-adversarial-review.md +441 -0
  12. package/docs/architecture/3.0-r5-browser-go-no-go.md +165 -0
  13. package/docs/architecture/3.0-r5-browser-typescript-gate.md +105 -0
  14. package/docs/architecture/3.0-r6-compat-retirement.md +203 -0
  15. package/docs/architecture/3.0-r7-public-api.md +151 -0
  16. package/docs/architecture/3.0-r8-ci-release.md +248 -0
  17. package/docs/architecture/3.0-r9-final-audit.md +370 -0
  18. package/docs/architecture/compat-inventory.md +26 -34
  19. package/docs/architecture/dsh-compatibility-matrix.md +65 -54
  20. package/docs/architecture/dsh-support-window.md +30 -22
  21. package/docs/architecture/final-closure-audit.md +2 -0
  22. package/docs/releases/v2.3.0.md +53 -0
  23. package/docs/releases/v3.0.0.md +85 -0
  24. package/entry.js +9 -57
  25. package/index.js +268 -761
  26. package/lib/agent-request-route-authority.js +1 -20
  27. package/lib/catalog-corrections.js +1 -2
  28. package/lib/client-maintenance-actions.js +145 -0
  29. package/lib/client-presentation-boundary-main.js +75 -17
  30. package/lib/client-presentation-boundary.js +53 -28
  31. package/lib/client.js +246 -144
  32. package/lib/core-apply-lifecycle.js +41 -0
  33. package/lib/core-cache.js +87 -0
  34. package/lib/core-primitives.js +91 -278
  35. package/lib/core-vision-surface-domain.js +63 -0
  36. package/lib/core-vision-surface.js +11 -77
  37. package/lib/delegated-call-config.js +15 -24
  38. package/lib/desktop-screenshot-tool.js +262 -0
  39. package/lib/doctor-cli.js +0 -0
  40. package/lib/doctor-runtime.js +4 -1
  41. package/lib/dsh-contract-compat.js +37 -256
  42. package/lib/dsh-host-capabilities.js +3 -9
  43. package/lib/dsh-settings-017-compat.js +17 -10
  44. package/lib/dsh-support-window.js +3 -3
  45. package/lib/file-logger.js +8 -3
  46. package/lib/grounding-coordinate-runtime.js +1 -2
  47. package/lib/http-body-limit.js +97 -79
  48. package/lib/http-compat.js +1 -2
  49. package/lib/image-offload-compat.js +30 -21
  50. package/lib/image-resource-governor.js +210 -228
  51. package/lib/legacy-global-proxy-boundary.js +46 -3
  52. package/lib/live-model-client-prelude.js +12 -4
  53. package/lib/live-model-discovery.js +134 -43
  54. package/lib/local-remote-settings-permission.js +33 -7
  55. package/lib/local-vision-stabilizer.js +31 -17
  56. package/lib/maintenance-routes.js +134 -0
  57. package/lib/native-image-coexistence.js +15 -3
  58. package/lib/ollama-cold-start.js +87 -23
  59. package/lib/pi-ai-bridge-wire-compat.js +3 -2
  60. package/lib/proxy-dispatcher-pool.js +151 -92
  61. package/lib/proxy-routing.js +75 -51
  62. package/lib/proxy-url-compat.js +3 -10
  63. package/lib/public-config.js +36 -0
  64. package/lib/public-entry.d.ts +148 -0
  65. package/lib/public-entry.js +19 -11
  66. package/lib/remote-settings-bridge.js +11 -0
  67. package/lib/remote-settings-risk-client-boundary.js +155 -0
  68. package/lib/remote-settings-risk-confirmation.js +17 -105
  69. package/lib/replay-delegation.js +12 -7
  70. package/lib/replay-envelope-v2-compat.js +12 -7
  71. package/lib/runtime-composition.js +127 -34
  72. package/lib/runtime-i18n-boundary.js +10 -11
  73. package/lib/screenshot-source-boundary.js +2 -2
  74. package/lib/session-affinity-runtime.js +113 -97
  75. package/lib/session-affinity.js +89 -76
  76. package/lib/session-event-history-compat.js +30 -0
  77. package/lib/session-message-source-compat.js +7 -3
  78. package/lib/session-query-readers.js +263 -0
  79. package/lib/session-surface-compat.js +30 -31
  80. package/lib/session-surface-policy-domain.js +85 -0
  81. package/lib/session-surface-policy.js +2 -111
  82. package/lib/session-turn-resolver.js +2 -6
  83. package/lib/session-vision-attachment-index.js +143 -0
  84. package/lib/session-vision-delegation-boundary.js +34 -0
  85. package/lib/session-vision-delegation.js +22 -0
  86. package/lib/session-vision-index.js +179 -116
  87. package/lib/session-vision-mode-authority.js +229 -192
  88. package/lib/session-vision-mode-boundary.js +65 -22
  89. package/lib/session-vision-policy-domain.js +304 -0
  90. package/lib/session-vision-policy.js +104 -0
  91. package/lib/session-vision-state.js +368 -378
  92. package/lib/settings-client-017-compat.js +9 -7
  93. package/lib/settings-client-loader-lifecycle.js +129 -0
  94. package/lib/sharp-runtime.js +0 -7
  95. package/lib/structured-flow-hardening.js +25 -6
  96. package/lib/tesseract-exec-compat.js +9 -1
  97. package/lib/turn-budget-context.js +47 -41
  98. package/lib/update-check.js +11 -2
  99. package/lib/vision-attachment-handle-runtime.js +176 -156
  100. package/lib/vision-backend-runtime-policy.js +19 -2
  101. package/lib/vision-background-benchmark.js +41 -4
  102. package/lib/vision-background-failure-policy.js +41 -41
  103. package/lib/vision-background-stop-store-core.js +217 -0
  104. package/lib/vision-background-stop-store.js +8 -179
  105. package/lib/vision-capability-benchmark-service.js +1 -0
  106. package/lib/vision-capability-benchmark.js +11 -61
  107. package/lib/vision-capability-evidence.js +35 -0
  108. package/lib/vision-capability-fingerprint.js +72 -0
  109. package/lib/vision-capability-identity.js +116 -61
  110. package/lib/vision-capability-router.js +13 -33
  111. package/lib/vision-chunk-assembler.js +95 -0
  112. package/lib/vision-diagnostics-routes.js +246 -0
  113. package/lib/vision-evidence-guidance.js +3 -1
  114. package/lib/vision-execution-order-apply.js +45 -55
  115. package/lib/vision-execution-order.js +19 -19
  116. package/lib/vision-execution-policy.js +12 -7
  117. package/lib/vision-model-registry.js +30 -17
  118. package/lib/vision-provider-transport.js +137 -176
  119. package/lib/vision-routing-authority.js +47 -48
  120. package/lib/vision-routing-product.js +26 -29
  121. package/lib/vision-routing-settings-prelude.js +8 -3
  122. package/lib/vision-runtime-performance-store.js +166 -0
  123. package/lib/vision-runtime-performance.js +13 -142
  124. package/lib/vision-toggle-root-hardening.js +22 -5
  125. package/lib/vision-tool-runtime-boundary.js +104 -31
  126. package/lib/web/dsh-settings-017-root-transport.js +27 -12
  127. package/lib/web/remote-settings-client.js +6 -9
  128. package/lib/web-capability-boundary.js +17 -7
  129. package/lib/wrapper-directory.js +14 -23
  130. package/package.json +56 -20
  131. package/lib/android-attachment-compat.js +0 -244
  132. package/lib/settings-client-rc8-lifecycle.js +0 -397
@@ -0,0 +1,370 @@
1
+ # DVR 3.0 R9 — Final architecture audit
2
+
3
+ Status: **complete**
4
+
5
+ Implementation checkpoint audited:
6
+
7
+ - branch: `3.0`
8
+ - runtime/source HEAD: `1e331b1b8f8ea74a5cd38a1347f4e0bd13ef9ef9`
9
+ - package version at audit: `2.3.0`
10
+ - 3.0 PR: none
11
+ - 3.0 release/tag: none
12
+
13
+ R9 is the final architecture audit for the 3.0 typed-architecture consolidation. It
14
+ re-runs the ownership, lifecycle, dependency-cycle, browser, compatibility, package,
15
+ Node 22/24, supported-DSH, Desktop, adversarial, property, resource and release gates
16
+ defined by the 3.0 plan.
17
+
18
+ The result is a closure, not a repository-wide TypeScript conversion.
19
+
20
+ ## Final architecture shape
21
+
22
+ 3.0 ends with the same core principle with which it started:
23
+
24
+ ```text
25
+ DSH public contracts
26
+ |
27
+ v
28
+ narrow runtime-validated Host boundaries
29
+ |
30
+ v
31
+ typed DVR semantic owners
32
+ |
33
+ v
34
+ Authority -> Evidence -> Planner -> Execution
35
+ | |
36
+ +------ composition ----+
37
+ |
38
+ v
39
+ mature Core
40
+ ```
41
+
42
+ TypeScript was used where it reduces concrete ownership, lifecycle or contract drift
43
+ risk. Mature algorithmic JavaScript and the browser client remain JavaScript where a
44
+ language conversion would add build/declaration complexity without moving an
45
+ architectural boundary.
46
+
47
+ ## Final source/package checkpoint
48
+
49
+ At the audited implementation HEAD:
50
+
51
+ ```text
52
+ canonical runtime TS owners 38
53
+ canonical public declarations 1
54
+ canonical package artifacts 182
55
+ tracked generated artifacts 0
56
+
57
+ browser client bytes 261672
58
+ browser hard gate 262144
59
+ browser headroom 472
60
+
61
+ package-root runtime exports 12
62
+ runtime-composition.js lines 483
63
+ ```
64
+
65
+ The final source-to-artifact evidence digest is:
66
+
67
+ ```text
68
+ 1949633432f7e284eec19fab4bd4e75a303e33bfe60f375ddf958c3a2343d48a
69
+ ```
70
+
71
+ The validation checkout was clean.
72
+
73
+ ## R9 findings and repairs
74
+
75
+ R9 was not a ceremonial re-run. It found several integration defects that ordinary
76
+ unit/CI coverage did not expose and repaired them before closure.
77
+
78
+ ### 1. Frozen Host Dispatcher Proxy invariant
79
+
80
+ The typed provider transport correctly moved DVR toward the public Undici Dispatcher
81
+ contract, but the per-hop wrapper originally used the borrowed Host dispatcher itself as
82
+ a JavaScript Proxy target.
83
+
84
+ A Host dispatcher may expose `dispatch` as a frozen/non-configurable own property. A
85
+ Proxy `get` trap that substitutes another dispatch function then violates ECMAScript
86
+ Proxy invariants and throws before network dispatch.
87
+
88
+ R9 changed the wrapper to use a neutral shell with the same prototype while forwarding
89
+ all non-dispatch reads/method calls to the borrowed fallback dispatcher.
90
+
91
+ Result:
92
+
93
+ - DVR still does not own or close the borrowed fallback;
94
+ - full Dispatcher method/event surface remains available;
95
+ - prototype/instance-style compatibility is preserved;
96
+ - the wrapper can safely override only the dispatch routing seam.
97
+
98
+ The transport regression suite passes after the repair.
99
+
100
+ ### 2. Cross-repository Host workflows still assumed tracked artifacts
101
+
102
+ R1 removed `entry.js`, `index.js` and `lib/**` from Git. Several real-Host and exact
103
+ source workflows still checked DVR out under `dvr/` and immediately handed that checkout
104
+ to DSH as if generated package artifacts were tracked.
105
+
106
+ This caused exact-source failures such as:
107
+
108
+ ```text
109
+ Cannot find .../dvr/lib/dsh-contract-compat.js
110
+ ```
111
+
112
+ and real Host/browser failures where the package topology was incomplete.
113
+
114
+ R9 updated every current cross-repository DVR checkout workflow to materialize the
115
+ package explicitly:
116
+
117
+ ```text
118
+ pnpm install --frozen-lockfile --ignore-scripts
119
+ pnpm build
120
+ pnpm build:check
121
+ ```
122
+
123
+ before DSH consumes the package.
124
+
125
+ A permanent architecture gate now requires one explicit materialization step per current
126
+ `path: dvr` checkout job.
127
+
128
+ ### 3. Peer-admission gate had a stale hard-coded DSH peer list
129
+
130
+ The Host admission evaluator assumed DVR declared only two DSH peers. 3.0 legitimately
131
+ uses the public `@deepseek-ai/dsh-storage-domain` type contract for the optional durable
132
+ Session policy sidecar, so the hard-coded peer list drifted from the package manifest.
133
+
134
+ R9 changed admission verification to derive the complete DSH peer set from
135
+ `package.json` rather than silently maintaining a second list.
136
+
137
+ This does not broaden admission. The same compatibility expression is still evaluated for
138
+ every declared DSH peer.
139
+
140
+ ### 4. Optional Cordis capabilities were read as direct service properties
141
+
142
+ Real DSH Host/Desktop runs exposed an important Cordis lifecycle rule that ordinary object
143
+ fixtures did not model: directly reading an undeclared optional service property can turn
144
+ capability detection into a hard pending dependency.
145
+
146
+ R9 repaired three seams:
147
+
148
+ - Session projection lookup now uses `Context#get('sessionProjections')`;
149
+ - optional storage-domain lookup now uses `Context#get('storageDomain')`;
150
+ - Agent delegation binding now enters through
151
+ `ctx.inject(['agents'], agentsCtx => ...)`.
152
+
153
+ Regression fixtures now deliberately throw on direct optional service-property reads so a
154
+ future refactor cannot accidentally recreate the hard dependency.
155
+
156
+ This preserves the intended ownership model:
157
+
158
+ ```text
159
+ optional capability
160
+ -> capability-safe Host lookup / explicit lifecycle child
161
+ -> narrow DVR boundary
162
+ ```
163
+
164
+ instead of:
165
+
166
+ ```text
167
+ optional capability
168
+ -> implicit Cordis dependency
169
+ -> plugin remains pending
170
+ ```
171
+
172
+ ## Local final-audit matrix
173
+
174
+ All final local evidence below was re-run at
175
+ `1e331b1b8f8ea74a5cd38a1347f4e0bd13ef9ef9`.
176
+
177
+ ### Build / source ownership
178
+
179
+ ```text
180
+ build success
181
+ build:check 182/182 artifacts in sync
182
+ source ownership lint success
183
+ source -> artifact evidence success
184
+ Host typecheck success
185
+ Client typecheck success
186
+ ```
187
+
188
+ ### Full runtime suite
189
+
190
+ ```text
191
+ main suite 1588 tests / 1587 pass / 0 fail / 1 skip
192
+ backend suite 9 tests / 9 pass / 0 fail
193
+ ```
194
+
195
+ ### Architecture / composition / transport
196
+
197
+ ```text
198
+ 87 / 87 pass
199
+ ```
200
+
201
+ Coverage includes ownership closure, dependency-cycle audit, composition, Session runtime
202
+ parity, execution-order wiring, Core surface projection and provider transport.
203
+
204
+ ### Browser
205
+
206
+ ```text
207
+ 166 / 166 pass
208
+ ```
209
+
210
+ The 256 KiB single-file gate remains unchanged.
211
+
212
+ ### Compatibility
213
+
214
+ ```text
215
+ 118 / 118 pass
216
+ ```
217
+
218
+ ### Resource / lifecycle
219
+
220
+ ```text
221
+ 35 / 35 pass
222
+ ```
223
+
224
+ ### Property fuzz
225
+
226
+ ```text
227
+ 5 / 5 pass
228
+ ```
229
+
230
+ ### Adversarial fuzz
231
+
232
+ ```text
233
+ 500 cases passed
234
+ seed = 1592639710
235
+ ```
236
+
237
+ ## Main CI
238
+
239
+ Current implementation HEAD CI:
240
+
241
+ ```text
242
+ run 36863198103
243
+ HEAD 1e331b1b8f8ea74a5cd38a1347f4e0bd13ef9ef9
244
+ conclusion: success
245
+ ```
246
+
247
+ This includes the 3.0 packed-public-API gate together with Node 22/24 and native package
248
+ coverage.
249
+
250
+ ## Supported DSH exact-source matrix
251
+
252
+ Final R9 run:
253
+
254
+ ```text
255
+ DSH exact source contract
256
+ run 36864403940
257
+ HEAD 1e331b1b8f8ea74a5cd38a1347f4e0bd13ef9ef9
258
+ conclusion: success
259
+ ```
260
+
261
+ The matrix covers the admitted 0.1.5/0.1.7 source trains across Ubuntu, macOS and Windows.
262
+
263
+ The public Host floor therefore remains evidence-backed; R9 found no reason to raise it.
264
+
265
+ ## DSH 0.1.7 real Host/Desktop
266
+
267
+ Final R9 run:
268
+
269
+ ```text
270
+ DSH 0.1.7 real Host smoke
271
+ run 36864412738
272
+ HEAD 1e331b1b8f8ea74a5cd38a1347f4e0bd13ef9ef9
273
+ conclusion: success
274
+ ```
275
+
276
+ Passed:
277
+
278
+ - real Host + Chromium;
279
+ - macOS real Desktop renderer;
280
+ - Windows Desktop Host / Node 22.19.0;
281
+ - Windows Desktop Host / Node 24.21.0.
282
+
283
+ ## DSH 0.2.0-rc.2 real Host/Desktop
284
+
285
+ Final R9 run:
286
+
287
+ ```text
288
+ DSH 0.2.0-rc.2 validation
289
+ run 36864396216
290
+ HEAD 1e331b1b8f8ea74a5cd38a1347f4e0bd13ef9ef9
291
+ conclusion: success
292
+ ```
293
+
294
+ Passed:
295
+
296
+ - real Host + Chromium;
297
+ - Windows Desktop Host / Node 22.19.0;
298
+ - Windows Desktop Host / Node 24.21.0;
299
+ - exact source / Ubuntu;
300
+ - exact source / Windows;
301
+ - exact source / macOS including real Desktop lifecycle.
302
+
303
+ ## Negative architecture audit
304
+
305
+ R9 explicitly rechecked the 3.0 non-goals.
306
+
307
+ Production source contains no introduced:
308
+
309
+ - `DvrContext`;
310
+ - giant `HostFacade`;
311
+ - generic service locator / DI container;
312
+ - global current owner / registry;
313
+ - `Object.create(core)` facade;
314
+ - private DSH `/src/` production import;
315
+ - `@ts-ignore` or `@ts-nocheck` suppression.
316
+
317
+ `runtime-composition.js` remains a composition root rather than becoming a second Core.
318
+
319
+ R9 did not:
320
+
321
+ - convert mature Core merely for TypeScript percentage;
322
+ - raise the browser size gate;
323
+ - introduce a browser bundler/minifier as an architecture fix;
324
+ - delete runtime validation;
325
+ - collapse Host and Client compiler worlds;
326
+ - narrow historical durable-data compatibility;
327
+ - raise the DSH Host floor without evidence.
328
+
329
+ ## Roadmap result
330
+
331
+ ```text
332
+ R0 baseline / contract ledger complete
333
+ R1 source / artifact boundary complete
334
+ R2 type infrastructure / Host boundaries complete
335
+ R3 DVR domain types complete
336
+ R4 composition / mature Core complete
337
+ R5 Browser Client complete / production TS switch No-Go
338
+ R6 compatibility retirement / Host floor complete
339
+ R7 public API complete
340
+ R8 CI / release complete
341
+ R9 final architecture audit complete
342
+ ```
343
+
344
+ The R4 result does not mean every mature-Core file became TypeScript. It means the
345
+ high-value composition/lifecycle seams were consolidated without creating the forbidden
346
+ declaration/facade graph; low-value algorithmic conversion was intentionally left out.
347
+
348
+ ## Final 3.0 architecture verdict
349
+
350
+ The architecture work described by the 3.0 plan is complete.
351
+
352
+ 3.0 now has:
353
+
354
+ - one canonical source tree;
355
+ - explicit generated package artifacts;
356
+ - strict, separate Host and Client compiler worlds;
357
+ - typed high-value lifecycle/domain owners;
358
+ - runtime validation at dynamic boundaries;
359
+ - explicit provider/resource/Session ownership;
360
+ - an intentionally narrow package-root runtime/type API;
361
+ - evidence-based compatibility retention/retirement;
362
+ - a deliberate Browser TypeScript No-Go rather than a weakened size/build contract;
363
+ - release and packed-package gates aligned with canonical source ownership;
364
+ - real Host/Desktop evidence across the supported DSH window.
365
+
366
+ The next work should therefore be release preparation or bug-driven follow-up, not another
367
+ architecture migration pass.
368
+
369
+ No PR, merge to `main`, 3.0 version bump, tag or formal 3.0 release is performed by
370
+ this R9 closure.
@@ -1,36 +1,30 @@
1
1
  # Compatibility seam inventory
2
2
 
3
- P0 records why each major compatibility seam exists and the condition that permits its removal. This inventory is normative for 2.x convergence: a shim without an exit criterion is architectural debt that cannot silently become permanent.
3
+ P0 records why each major compatibility seam exists and the condition that permits its removal. This inventory is normative for DVR 2.3 convergence: a shim without an exit criterion is architectural debt that cannot silently become permanent.
4
4
 
5
5
  ## `lib/dsh-contract-compat.js`
6
6
 
7
- - **Reason:** preserve released attachment/settings/provider-ownership behavior across the supported DSH window.
8
- - **Host gap:** rc.6 has the single-attachment contract; later Hosts add batch save, max-dimension policy and newer settings/provider lifecycle behavior.
9
- - **First needed for:** minimum rc.6 support and the subsequent rc.7/rc.8 attachment migration.
10
- - **Feature detection:** `attachments.saveImages`, attachment `imageLimits`, settings registration/scope functions, and LLM registration methods. The batch-attachment generation is also the semantic boundary where `deepseek-official` remains Host-owned instead of being reconstructed by DVR. No version-string branch.
11
- - **Removal condition:** minimum supported DSH natively exposes the required attachment/settings/provider seams and legacy profile overlays are outside support.
12
- - **Tests:** `rc6-rc7-compat`, `rc6-real-settings-persistence`, `attachment-admission-policy`, `dsh-host-capabilities`, minimum/legacy/current contract CI.
7
+ - **2.3 state:** `retain-host-gap`.
8
+ - **Reason:** keep supported settings/provider-ownership contracts and durable attachment-policy migrations centralized without reviving pre-floor Host ownership.
9
+ - **Host gap:** the DVR 2.3 window spans multiple Settings/Config generations, while persisted historical `attachment-local` profile overlays can still shadow current image-limit/normalization defaults after the Host is upgraded.
10
+ - **First needed for:** supported Settings lifecycle convergence plus durable profile migration. The pre-`0.1.5` single-attachment / DeepSeek-provider reconstruction path is retired in R2.3.
11
+ - **Feature detection:** attachment `imageLimits` / normalization shape, settings registration/scope functions, and LLM registration ownership. `attachments.saveImages` remains a diagnostic/ownership fact; it no longer authorizes DVR to synthesize an official DeepSeek provider.
12
+ - **Removal condition:** the supported Settings lifecycle has one native contract and durable profiles containing the historical attachment policy overlay are migrated or explicitly outside the data-compatibility window.
13
+ - **Tests:** `dsh-host-compat` (retained durable/current cases), `minimum-host-settings-persistence`, `attachment-admission-policy`, `dsh-host-capabilities`, minimum/current/rc2 contract CI.
13
14
 
14
15
  ## `lib/adapter-update-coalescer.js`
15
16
 
17
+ - **2.3 state:** `retain-host-gap`.
16
18
  - **Reason:** keep Vision Router-owned duck-typed adapters compatible with Host `prepareCall` dispatch and prevent synchronous adapter-topology events from recursively reconciling forever.
17
- - **Host gap:** older plugin adapters do not inherit the Host adapter base class; supported Host generations can emit adapter updates synchronously during registration.
18
- - **First needed for:** DSH 0.1.1 `prepareCall` and atomic registration behavior.
19
+ - **Host gap:** Vision Router intentionally owns several plain/duck-typed adapters instead of inheriting the Host adapter base class; supported Host generations call base-class contracts and can emit adapter updates synchronously during registration.
20
+ - **First needed for:** Host adapter-contract evolution (`prepareCall`, later image-request pricing) and synchronous registration reconciliation. The original version labels are historical origin only, not a current support dependency.
19
21
  - **Feature detection:** adapter-local `prepareCall` presence; actual `llm/adapters-updated` event path. No version inference.
20
22
  - **Removal condition:** every supported Vision Router adapter directly satisfies the Host adapter contract and supported Host event semantics no longer require the bounded coalescer.
21
23
  - **Tests:** `adapter-prepare-call-compat`, `runtime-boundary-fixes`, current-contract Host smoke.
22
24
 
23
- ## `lib/android-attachment-compat.js`
24
-
25
- - **Reason:** allow the minimum Host path to survive Termux/Android attachment persistence permission boundaries without taking ownership on batch-capable Hosts.
26
- - **Host gap:** file-backed attachment storage can fail with `EACCES`/`EPERM` in Android/Termux environments on the legacy path.
27
- - **First needed for:** Android/Termux support while rc.6 remains minimum.
28
- - **Feature detection:** Android/Termux environment, permission-boundary error and absence of the batch attachment contract.
29
- - **Removal condition:** minimum supported DSH owns a working Android attachment implementation for the same path and the fallback is no longer reachable.
30
- - **Tests:** `android-attachment-compat`, image-resource/resource-retention tests.
31
-
32
25
  ## `lib/replay-envelope-v2-compat.js`
33
26
 
27
+ - **2.3 state:** `product-compat`.
34
28
  - **Reason:** preserve delegated replay identity when producer provider/model moved into durable pi-ai replay envelope v2.
35
29
  - **Host gap:** older Vision Router replay code expected producer identity at the top level.
36
30
  - **First needed for:** rc.7 replay-envelope v2 histories.
@@ -40,6 +34,7 @@ P0 records why each major compatibility seam exists and the condition that permi
40
34
 
41
35
  ## `lib/pi-ai-bridge-wire-compat.js`
42
36
 
37
+ - **2.3 state:** `retain-host-gap`.
43
38
  - **Reason:** keep the legacy direct image bridge transport-equivalent to pi-ai declared wire compatibility and, while upstream lacks the OpenCode-specific carrier, project Vision Router-owned session affinity onto the final Go wire without taking ownership of ordinary Host traffic. `lib/session-affinity-runtime.js` is the scoped AsyncLocalStorage companion; it carries affinity only while a Router-owned lazy stream is executing.
44
39
  - **Host gap:** the direct bridge predates route/model wire metadata such as max-token fields and route-owned headers; current DSH/pi-ai accepts `GenerateOptions.sessionId` but emits generic affinity carriers rather than OpenCode Go's required `x-opencode-session`.
45
40
  - **First needed for:** DSH 0.1.1 pi-ai declared provider/wire compatibility; OpenCode Go's September 2026 required session header.
@@ -47,17 +42,19 @@ P0 records why each major compatibility seam exists and the condition that permi
47
42
  - **Removal condition:** remove legacy bridge recovery when every supported Host executes that image path through native pi-ai wire facts; remove the scoped OpenCode projection independently once every supported DSH/pi-ai path emits `x-opencode-session` from `GenerateOptions.sessionId`. The native header must win before deletion so the compatibility rule self-retires.
48
43
  - **Tests:** `pi-ai-bridge-wire-compat`, real `opencode-session-wire-contract`, native process-restart/cold-resume contract.
49
44
 
50
- ## `lib/settings-client-rc8-lifecycle.js`
45
+ ## `lib/settings-client-loader-lifecycle.js`
51
46
 
52
- - **Reason:** keep browser settings lifecycle coherent across legacy and current Host client generations.
53
- - **Host gap:** settings client attachment/replacement lifecycle is not identical across the support window.
54
- - **First needed for:** rc.8-era settings UI coexistence.
55
- - **Feature detection:** actual client/runtime lifecycle surfaces; never the Host version label.
56
- - **Removal condition:** supported Hosts expose one stable settings client lifecycle and the compatibility branch is proven unreachable by contract tests.
47
+ - **2.3 state:** `retain-host-gap`.
48
+ - **Reason:** keep current Settings permission/risk capability owners attached when the Host module system switches registrations from queue to live loading. The legacy in-page `settings-rc8-lifecycle` marker/sentinel is intentionally retained only for mixed-generation/HMR idempotency; source/API ownership is capability-named.
49
+ - **Host gap:** immutable supported sources from 0.1.5-rc.1 through 0.2.0-rc.2 still replace the live module `load` function during `create()`, so one boot-time wrapper is not stable across the complete client lifecycle.
50
+ - **First needed for:** the older Settings UI coexistence work; retained now because the same loader replacement remains present on supported Hosts, not because rc.8 itself is supported.
51
+ - **Feature detection:** actual `__ModuleLoader__.create/load` lifecycle and current Settings surfaces; never the Host version label.
52
+ - **Removal condition:** supported Hosts expose one stable Settings client attachment lifecycle (or the shared carrier gives DVR a native post-create hook) and current product permission/risk wrappers no longer require reattachment.
57
53
  - **Tests:** settings IA, client lifecycle, remote-settings and Web acceptance regressions.
58
54
 
59
55
  ## `lib/http-compat.js`
60
56
 
57
+ - **2.3 state:** `product-compat`.
61
58
  - **Reason:** isolate evidenced provider/model wire quirks from generic visual HTTP execution.
62
59
  - **Host gap:** this is provider compatibility rather than a DSH Host gap; some OpenAI-compatible endpoints reject otherwise valid generic payload shapes.
63
60
  - **First needed for:** model-family quirks such as GLM-4V-Flash output limits and image-only message handling.
@@ -65,17 +62,9 @@ P0 records why each major compatibility seam exists and the condition that permi
65
62
  - **Removal condition:** upstream endpoint behavior becomes generic-compatible for a rule and regression evidence confirms the preset is no longer needed.
66
63
  - **Tests:** `http-compat`, provider HTTP regression tests.
67
64
 
68
- ## `lib/vision-provider-transport.js` process/profile registry
69
-
70
- - **Reason:** carry the Router-owned provider transport into compatibility callers whose mature function signatures still accept only a raw `fetch` or use an internal direct HTTP call, while keeping Router traffic off the process-global fetch patch.
71
- - **Host gap:** this is an internal composition gap rather than a DSH version persona: `fetchWithOpenAICompatibility(...)` and the Anthropic catalog-correction path do not yet receive a `VisionProviderTransport` parameter explicitly.
72
- - **First needed for:** provider-scoped transport ownership and proxy narrowing without rewriting the mature compatibility call signatures in the same migration.
73
- - **Feature detection:** explicit transport-aware callers bypass the registry; only compatibility paths that call `currentVisionProviderTransport()` consume the currently installed process/profile transport. The registry never patches `globalThis.fetch`. Router-owned and scoped Host-owned explicit proxies share one lease/retire dispatcher pool. First-hop `proxyHosts` admission preserves the no-Undici Host path for non-matches; admitted requests use a request-scoped selector that re-checks every redirect origin and delegates non-matches to the request-start Host/caller dispatcher.
74
- - **Removal condition:** every Router-owned compatibility caller receives `VisionProviderTransport` explicitly, production has zero reads of `currentVisionProviderTransport()`, and the install/release registry can be removed without changing proxy, redirect-hop authority, credential, bounded-body, cancellation, or dispatcher-lifecycle behavior.
75
- - **Tests:** `vision-provider-transport` (A→B lifecycle, proxy clear, pending-construction unload, synchronous loader failure, real Fetch listed→unlisted redirect, initial-unlisted no-import and explicit-caller fallback), `legacy-global-proxy-boundary` (scoped Host-owned redirect and pool cleanup), `http-compat`, `catalog-corrections`, P2 Data Boundary provider-transport Node 22/24, Host pack/install smoke.
76
-
77
65
  ## `lib/legacy-global-proxy-boundary.js`
78
66
 
67
+ - **2.3 state:** `retain-host-gap`.
79
68
  - **Reason:** preserve the explicit Vision Router proxy override for Host-owned/raw-fetch visual providers without granting that configuration process-wide routing authority. Router-owned HTTP already uses `VisionProviderTransport`; blank `proxy` leaves the compatibility wrapper fully transparent.
80
69
  - **Host gap:** DSH 0.1.5 owns ordinary process egress, but a Host adapter invoked through `ctx.llm.stream()` still exposes no DVR-owned request/dispatcher parameter for a vision-only SOCKS/selective override. A separate legacy direct whole-turn mode (`routing=true` plus blank `chainRoute`) also hands control to the Host after the DVR hook returns, leaving no adapter-iteration scope to authorize.
81
70
  - **First needed for:** legacy/custom Host-owned visual provider compatibility when users configure a Vision Router-specific proxy override.
@@ -86,6 +75,7 @@ P0 records why each major compatibility seam exists and the condition that permi
86
75
 
87
76
  ## `lib/legacy-core-vision-policy-bridge.js`
88
77
 
78
+ - **2.3 state:** `retain-host-gap`.
89
79
  - **Reason:** preserve the two remaining pre-step compatibility behaviors after Core policy ownership moved to explicit session/Core surfaces: reuse the exact `SessionMemoryView` for text-only image-history rewrite, and expose exact current-turn durable attachment IDs as read-only model context for Vision Router-owned wrappers.
90
80
  - **Host gap:** the supported Host pre-step path does not natively provide both an exact session-scoped visual-memory rewrite seam for text-only fallback and a model-readable durable attachment-reference seam for Router-owned image turns.
91
81
  - **First needed for:** the Core/session ownership migration that removed Settings/config impersonation while retaining these two real pre-step behaviors.
@@ -95,6 +85,7 @@ P0 records why each major compatibility seam exists and the condition that permi
95
85
 
96
86
  ## `lib/tesseract-exec-compat.js`
97
87
 
88
+ - **2.3 state:** `product-compat`.
98
89
  - **Reason:** own the single process-wide `promisify(execFile)` compatibility boundary for the two narrow child-process cases Vision Router still needs: materializing Tesseract stdin image bytes, and replacing only Core's exact legacy Windows `VirtualScreen`/`CopyFromScreen` desktop-capture command with a per-monitor-DPI-safe equivalent. One owner prevents cleanup-order bugs from independently stacked `execFile` wrappers.
99
90
  - **Host gap:** these are runtime/platform gaps rather than DSH semantic ownership: Node's async `execFile` path does not consume the historical OCR `options.input`, while non-DPI-aware Windows PowerShell virtualizes desktop metrics and can disagree with physical screen-copy coordinates on scaled/mixed-DPI displays.
100
91
  - **First needed for:** Node 24/local Tesseract process execution reliability; Windows scaled/mixed-DPI `vision_screenshot` correctness (#340).
@@ -104,6 +95,7 @@ P0 records why each major compatibility seam exists and the condition that permi
104
95
 
105
96
  ## `lib/abort-signal-compat.js`
106
97
 
98
+ - **2.3 state:** `product-compat`.
107
99
  - **Reason:** keep Vision Router cancellation/deadline composition working when a supported DSH Host or bridge exposes `AbortSignal`/`AbortController` but omits the standard static `AbortSignal.any()` or `AbortSignal.timeout()` helpers used by the Router's runtime boundaries.
108
100
  - **Host gap:** some real Host/bridge environments can surface a partial AbortSignal runtime even though the declared Node support window normally provides both helpers, producing `AbortSignal.any is not a function` inside visual work.
109
101
  - **First needed for:** partial Host/bridge AbortSignal runtimes observed during Vision Router image execution and exact capability checks.
@@ -117,6 +109,6 @@ A compatibility seam may be deleted only when all of the following are true:
117
109
 
118
110
  1. its **Removal condition** is satisfied by the declared support window;
119
111
  2. the relevant capability is proved by a gating Host contract fixture or direct feature test;
120
- 3. deleting the seam leaves Node 22/24, minimum/legacy/current Host contracts and relevant platform tests green;
112
+ 3. deleting the seam leaves Node 22/24, minimum/current/mid-train/rc.2 Host evidence and relevant platform tests green;
121
113
  4. no Authority, Session, Storage or native-multimodal invariant changes as a side effect;
122
114
  5. the deletion is a focused change, not bundled into an unrelated routing/data-boundary refactor.