Repository navigation
Description
Completed — 21 September 2026
The shared scheduler/protocol implementation and WebScene PR #891 now satisfy the current installed-package proof that kept this issue open. On unchanged Code OSS 645f29cc, tested WebScene change 1412283 (merged without code changes as d3c030f), and AppScene cd0a02e, 20/20 launches retained the exact remote root, registered provider, five resolved children, five Explorer-model children, five visible rows, and 64-node DOM bound.
Resolve is 751.61 ms p50 / 762.64 ms p95 / 797.49 ms maximum. First-child paint is 1828.19 ms p50 / 1860.12 ms p95 / 1870.24 ms maximum; every launch satisfies the 2-second gate. Routed selector invalidation behavior remains covered by the focused native regressions, and the direct-subject optimization has an explicit A/B escape hatch.
The remaining workspace-file/multi-root, interaction, dependent-service, visual, and repeated lifecycle matrix stays in #252. No duplicate scheduler implementation remains scheduled.
Parent/product acceptance: #252
Release coordination: #227
Problem
An unchanged Code OSS vscode-remote workspace reaches the correct new-document root and registers the stock RemoteFileSystemProviderClient, but WebScene takes about eight seconds to complete the first direct IFileService.resolve for a five-entry local fixture. Chromium against the same Code OSS server/provider/root completes the resolve in 328 ms and paints the five Explorer rows in 715 ms.
This is below the picker/navigation/workspace-context layers already qualified by #247 and AppScene#124. It is a generic native WebScene request/response latency boundary in the remote filesystem path and blocks #252's provider/Explorer performance gate.
Retained evidence
Exact source inputs:
- VS Code OSS
645f29cc3176500b4b5762ba887cf2a7f0ffdf2c - WebScene
28d1d649e927c665ff05844197af44f223edf952 - AppScene
1420e227e52579a097e7ae52a2cadb41cf073e4d - Node
24.18.1 - fixture root
/private/tmp/webscene-247-fixture/beta
Clean native trace after await fileService.activateProvider('vscode-remote'):
- selected URI equals the only
IWorkspaceContextServiceroot - provider registered before resolve
resolve: 8,139.3 ms- first five Explorer rows: 12,324.0 ms from observer start
- resolved child set is exact:
.hidden.txt,readme-link,README.md,subdir/,unicodé.txt - rendered rows: 5; Explorer DOM nodes: 64
A separate overlapping run is retained as contaminated timing and excluded from the performance conclusion; it independently measured an almost identical 8,132.1 ms resolve.
Headless Chrome 153 against the same server build, stock provider, and exact root:
resolve: 328.2 ms- first five Explorer rows: 714.9 ms
- provider/root/resolved/model/rendered sets all exact
- observer sampling maximum: 0.5 ms
- 2 s resolve/paint gate passed
The browser observer revision only adds post-resolve Explorer-model polling. The activation and direct resolve path is byte-equivalent to the native trace. Earlier providerRegistered=false and empty model findings were observer-ordering false positives and are excluded.
Investigation
- Reduce the remote filesystem request/response path to the smallest same-origin WebSocket/channel fixture that reproduces native latency with a fast Chromium oracle.
- Attribute time across renderer enqueue, socket write/read, server channel handling, native event-loop wakeup, interop dispatch, and promise/microtask continuation.
- Check whether the fixed delay applies to the first request only, every request, reconnects, cancellation, errors, and concurrent requests.
- Fix the smallest generic WebScene owner contract. Keep Code OSS and its remote provider unchanged.
Acceptance
- A product-neutral browser/native oracle returns identical stat/read-directory results and error classes through the same request/response protocol.
- Cold and warm native p50/p95 are recorded against Chromium; the five-entry fixture completes resolve and first-child paint within 2 s.
- One logical provider request produces one bounded socket write and response; queue depth, queued bytes, tasks, DOM mutations, scene publications, and wakeups have explicit ceilings.
- Cancellation, disconnect/reconnect, denied/missing paths, malformed responses, and out-of-order concurrent responses settle once without stale delivery.
- A repeated lifecycle gate releases sockets, callbacks, promises, tasks, provider listeners, documents, and watcher handles; RSS/V8 heap growth is bounded.
- The unchanged Code OSS product trace preserves the exact selected URI, provider registration, five resolved/model/rendered children, and watcher readiness under the latency bounds.
- Directly related macOS/Linux native checks and the Chromium oracle pass before Qualify remote workspace bootstrap, Explorer contents, and watcher refresh #252 is requalified.
Current disposition — 18 September 2026
The implementation chain is complete: #297 closed its theme-continuation slice and the scheduler work from #287/#293/#289 landed through PR #347 as dbd7351a. Product-shaped direct evidence now keeps the 1.07 MiB protocol flush at 0.157 ms p95 / 0.274 ms max with bounded queues and flat V8 heap.
This issue requires no separate implementation. It remains open only for the same current-package #252 exact provider/root/first-child proof used to close #287, #293, and #289. If that run passes, close all four from the shared evidence; if it fails, attribute the new earliest boundary before opening another child.
Activity
wieslawsoltes commentedon Sep 17, 2026
The first generic defect is now split as native subissue #284 with focused PR #285.
Direct evidence for that split:
The correctly rebuilt and relinked unchanged Code OSS product trace shows #284 is necessary but not sufficient for this parent issue. Functional output remains exact—registered provider, selected URI equals the only workspace root, exact five resolved/model children, 5 rendered rows, 64 Explorer DOM nodes—but
resolvestill takes 7,641.1 ms and first paint 11,577.4 ms. Log:/private/tmp/vscode-252-product-navigation-280-correct.log.Therefore #280 and #252 stay open. The remaining investigation must attribute time below the now-qualified socket wake/fairness boundary; PR #285 does not claim the product latency gate.
wieslawsoltes commentedon Sep 17, 2026
Post-merge control on exact WebScene
aa06172crules out the native harness's 100 ms host-evaluation polling as the remaining delay.The query-gated local observer stopped all host state evaluations and invalidations immediately after the first navigation handoff, then relied only on the in-page terminal console record. The unchanged Code OSS result was:
This matches the original 8.14 s boundary, so observer polling is excluded. #284's merged socket queue/wakeup gate remains independently qualified (max 23 competing MessagePort deliveries and stable V8 heap), while the remaining delay stays under #280. Investigation-only local vscode-demo commit:
a3ab610; product log:/private/tmp/vscode-252-product-navigation-280-no-host-poll.log.wieslawsoltes commentedon Sep 17, 2026
The one-shot, exact-package attribution trace on merged WebScene
aa06172cidentifies the remaining generic scheduler boundary and splits it to native subissue #287.Inputs were AppScene
1420e227, unchanged Code OSS645f29cc, Node 24.18.1, and local query-gated observer74b3b94atop validated no-host-poll observera3ab610. The app/server process group was terminated immediately after the terminal workspace record. Log:/private/tmp/vscode-252-product-navigation-280-attribution.log.Functional evidence remained exact:
vscode-remoteURI == only workspace root.hidden.txt,readme-link,README.md,subdir/,unicodé.txtAttribution:
Blob.arrayBuffer(): 1.532 ms aggregate, 0.041 ms maximumloadend: 658,518.7 ms aggregate across overlapping reads, 14,940.7 ms maximumThe byte counts align the native socket, Blob, and FileReader path. Blob copying, JS callbacks, and callback microtasks are small. The source-level boundary is task arbitration: ready Worker/MessagePort/WebSocket sources return before the runtime checks due timers, while FileReader schedules both its read start and terminal events with zero-delay timers. Continuous protocol traffic can therefore starve the timers required to consume its own responses.
#287 owns product-neutral fairness between async message sources and due timers, with direct native/browser, ordering, cancellation/reconnect, teardown, queue, scene, heap/RSS, and unchanged-product gates. #284 remains complete and is not reopened. #280 is reopened because #284 was necessary but did not satisfy this parent's product latency acceptance.
The instrumentation intentionally adds bounded observation and this run is attribution evidence, not a new performance qualification result. The clean no-host-poll 8,055.1 ms result remains the comparison baseline until #287 is fixed and the unchanged product is rerun.
wieslawsoltes commentedon Sep 17, 2026
#287's focused direct candidate proves timer fairness against the Worker/MessagePort/WebSocket group, but the unchanged product rerun shows that source group is not the full remaining #280 owner.
On local
0f92cf47rebased to WebScene mainaa786c0e, the 256-frame FileReader gate records p95 0.119–0.198 ms and maximum 0.272–0.716 ms, exact bytes/event order, ≤20 competing port deliveries, 514/514 timers, ≤4,482 microtasks, 2 scene builds, stable heap, and 47.6 MB RSS. Baseline fails the same gate.The exact AppScene
1420e227/ Code OSS645f29cc/ Node 24.18.1 product rerun remains correct but slow:Product log:
/private/tmp/vscode-252-product-navigation-287-candidate.log. #287 remains local/unpushed and does not close #280. The next measurement must distinguish other runtime task sources and non-task phases before another fix.wieslawsoltes commentedon Sep 17, 2026
The unchanged-product candidate timeline moves the remaining parent boundary to existing Worker/MessagePort owner #81; no duplicate defect is opened.
From
/private/tmp/vscode-252-product-navigation-287-candidate.log:AgentHost:remote Connected: 1789655993265The extension-host WebSocket opened after 1,247 ms, but the AgentHost connection milestone took roughly another 16.6 seconds. Once it connected, provider resolution and paint completed immediately. #81 already owns unchanged Code OSS's browser extension-host iframe, Worker, transferred MessagePort, handshake, responsiveness, and lifecycle acceptance, with #288/PR #245 owning the active-port lifetime overlap.
Dependency order is now: #81 packaged handshake/latency (coordinated with #288 as needed) → rerun #280 direct provider bound → rerun #252 Explorer 2 s bound. #287 remains a valid focused generic timer/task-source fairness finding, but its local candidate is independently insufficient for this parent.
wieslawsoltes commentedon Sep 17, 2026
The #81 phase trace refines this issue's upstream dependency. Local iframe/Worker/transferred-MessagePort startup completes in order, while the remote extension-host protocol takes 1,177 ms from connected transport to Ready and 4,379 ms from Ready to Initialized. That distinct owner is now #289 (native subissue of #81), separate from #288.
After the remote handshake, the separate AgentHost service connects and the exact five-child/five-row workspace result follows 99 ms later. Requalify this issue after #289: #289 → #280 → #252. Local #287 remains unpushed and is not sufficient.
wieslawsoltes commentedon Sep 17, 2026
Packaged receiver-boundary trace on unchanged Code OSS
645f29cc, AppScene1420e227, exact Node 24.18.1, and the current diagnostic package now separates the 4.2 s remote Ready → Initialized interval.Second workspace document:
_createExtHostInitData()settle: 426.90 msResource delivery remains fast: the iframe response was 0.899 ms / 6,786 bytes and the worker module response was 2.803 ms / 1,932,148 bytes. The exact selected URI/root, provider registration, five resolved/model children, five rendered rows, and 64 maximum Explorer DOM nodes all passed functionally. Peak app process-group RSS was 837,376 KiB. The bounded run terminated its complete process group and verification found no app/server/helper descendants.
The independent 20-cycle native product-neutral oracle is also fast (Ready p95 5.944 ms; Initialized p95 5.408 ms; socket dispatch p95 5 ms; FileReader p95 2.536 ms; Promise/microtask p95 0.0078 ms; serialization p95 0.213 ms). Chromium passes the same 43/43 contract (Ready and Initialized p95 1.7 ms). Therefore no generic WebScene implementation is justified from this evidence yet. The next trace must split the receiver side after the 1.07 MB init payload is sent: receipt/parse, init-data hydration, extension scan/activation, and Initialized response.
Retained evidence:
/private/tmp/vscode-252-product-handshake-289.logd85db2b31883b5f5f7e3a6747de96945c1810e792b0293a03df104a5dee0b761/private/tmp/vscode-252-product-handshake-289-process.txt/private/tmp/webscene-289-baseline.log/private/tmp/webscene-289-chrome-baseline-verify/results.json10fc9aawieslawsoltes commentedon Sep 17, 2026
Receiver-side instrumentation isolates the breach before Node parsing or extension initialization.
On the retained second workspace document:
ExtensionHostMainconstruction begins only after Initialized is sent, so extension scanning/activation cannot own the Ready → Initialized breach. The exact root/provider/five resolved children/five model children/five rendered rows/64-node result still passes functionally. The 50 s bounded observer waited for the later constructor completion marker, then terminated the complete process group; no app/server/extension-host descendants remained. Peak process-group RSS was 843,184 KiB.A size-matched control preserves the earlier fast baseline: the product-neutral native oracle sends a binary-compatible 1,071,424-byte payload for 20 cycles and reports Initialized p95 6.140 ms; Chromium passes 43/43 in 89 ms. The next reduced gate must add the actual Code OSS binary framing/compression and concurrent traffic/queue shape, retain enqueue → wire → server-receipt timing, and preserve this fast size-only control before any WebScene implementation.
Retained evidence:
/private/tmp/vscode-252-product-receiver-289.log(SHA-25651d5b4d696b5474e2210a1f13851b39531443030927fa148f6705ffc79aed160)/private/tmp/vscode-252-product-receiver-289-server.log(SHA-256372b41c577260eb7787ceeaaca6c7f6655ced1259f4a4d4e9715e6280cf2e9db)/private/tmp/vscode-252-product-receiver-289-process.txt/private/tmp/webscene-289-one-mib.log/private/tmp/webscene-289-chrome-one-mib-2/results.jsonda9db1a2 remaining items
wieslawsoltes commentedon Sep 17, 2026
Post-#281 qualification keeps #280 open. On exact main
1bd8596e, localb75d3795fixes the reduced 1,071,425-byte multi-source timer oracle (max 3617.66 ms → 0.204 ms) while preserving Worker/ServiceWorker/MessagePort/WebSocket rotation. However, unchanged packaged Code OSS still waited 3698 ms from protocol-send request to nativeWebSocket.sendentry. Native send then returned in 0.783 ms, its microtask ran in 0.834 ms, and the remote Initialized reply arrived 184 ms after send entry.This excludes WebSocket wire throughput as the remaining bottleneck and shows that timer-vs-async arbitration alone is insufficient. The next investigation is the other product runtime task tiers that can return before due timers. No candidate PR will be published while #252 misses its two-second gate; draft #292 also has a live runtime-task path collision.
Evidence:
/private/tmp/vscode-252-product-b75d3795.log, SHA-256f58b40413fe5dd30567d0d6a3d207b668fd07bea96b594aae9c5568509a38252. All traced descendants were terminated and port 54759 released.wieslawsoltes commentedon Sep 17, 2026
#293's local candidate proves generic due-timer fairness against self-refilling window messages, but unchanged Code OSS still waits 3478 ms from protocol-send request to native
WebSocket.sendentry; Ready→Initialized is ~4102 ms. Native send itself is 0.815 ms and its microtask 0.857 ms. Therefore #280 remains open and the remaining owner is another pre-timer runtime tier or timer-eligibility boundary. No push/PR.Evidence:
/private/tmp/vscode-252-product-b485f6aa.log, SHA-256cb9b7c5c843da4badc2b8c7e35c2850b41598c70b7510afce7c94bee5b5a2a26. Full process cleanup and port release verified.wieslawsoltes commentedon Sep 17, 2026
The remaining #280 startup delay is now attributed below task arbitration to the built-in
light_vs.jsonfetch promise continuation: onedrain_fetch_tasktook 2457.000 ms, of which 2424.455 ms was the required microtask checkpoint and 32.530 ms style-batch finish. Response construction and promise settlement were only 0.012 ms. The overdue protocol timer's histogram assigned 2457.097 ms to that one fetch task.Opened #297 for the product-neutral theme continuation/DOM-CSS performance reduction. #287/#293 remain valid generic scheduler findings but neither qualifies unchanged #252. No push/PR.
Evidence:
/private/tmp/vscode-252-fetch-phases-7ad62971.log, SHA-256d1feb5b7970d56298ee80c2a49228dfc3060c4663dec3a2249b09e77c4d98b72; all traced processes terminated and port 57829 released.wieslawsoltes commentedon Sep 18, 2026
The exact AppScene
d4a73888/ WebScenedd39f118/ Code OSS645f29ccworkspace run now supplies the product evidence for this owner. Functional #252 output passes: exact remote root, provider registration, five resolved/model children, five visible rows, and 64 Explorer DOM nodes.The performance gate fails with a clear FileReader/completion split: 149 FileReader operations read 13,209,295 bytes, sum to 88,463.6 ms, and have a 2,219.39 ms maximum, while 149
Blob.arrayBuffer()calls for the same bytes sum to 1.11 ms with a 0.040 ms maximum. Initial provider stats take about 1.21-1.27 s; root readdir takes about 332 ms. This keeps #280 open and makes it the next workspace-performance implementation before #252 can close.Evidence:
/private/tmp/vscode-demo-workspace-dd39f11-d4a7388/. vscode-demo #8 adds a bounded compact summary because the verbose 149-call record exceeded the runtime diagnostic record cap.wieslawsoltes commentedon Sep 18, 2026
The latest exact installed-package rerun is functionally correct and refines the remaining performance owner back to #287 with a new concrete boundary:
loadend: 88,463.629 ms aggregate across overlapping reads, 2,219.394 ms maximum;Blob.arrayBuffer(): 1.111 ms aggregate, 0.040 ms maximum;PR #423 implements the product-neutral #287 follow-up: FileReader uses its own bounded browser task source instead of sharing the application timer backlog. The exact-main test-only control drains 4,096 timers before FileReader and takes 57.847 ms; the candidate completes in 0.405 ms after two competing timers. Native and Chrome pass the shared contract 48/48, and the existing 100-cycle/20-cycle protocol gates remain green with bounded work and flat settled V8 heap.
Do not close this parent from the reduced result. After #423 merges, rebuild the exact SDK/package and rerun the same unchanged-product workspace trace. Close #280/#252 only if resolve and first-child paint meet the two-second bound with exact functional output.
wieslawsoltes commentedon Sep 21, 2026
Exact current-package requalification on 21 September isolates the remaining #280 breach and starts a focused candidate.
Exact input:
cd0a02ecd15f0a635bccc242cdd657888db39e2562c4c6175fc55bbebb633eb18b5a94e7de613efe645f29cc3176500b4b5762ba887cf2a7f0ffdf2cf5594cd51d43f840b84426b2f33ba3c906dcd5b1c17623c759784e6078c47095The unchanged-product functional oracle passes: selected URI equals the only workspace root, the provider is registered, and the exact five fixture children appear in the provider result, Explorer model, and five visible rows with 64 Explorer nodes. Resolve is now 1,219.824 ms and passes the 2-second bound. First-child paint is 2,530.115 ms, so #280/#252 remain open.
The remaining timing signal is FileReader scheduling: 90 reads cover 11,833,296 bytes; matching
Blob.arrayBuffer()work is at most 0.0393 ms, while FileReader call-to-loadendis at most 1,114.299 ms. WebScene currently schedules one dedicated file-reading task forloadstartand a second task for terminal events, closing two microtask/style batches per protocol Blob.Local focused candidate
302e6d18keeps one asynchronous FileReader task open through the Blob promise checkpoint and orderedloadstart→progress→load→loadenddelivery. Abort, errors, immediate chained reads, native queue bounds, and event order remain covered. Pinned Node compatibility passes 8/8. The native gate passes 100 WebSocket cycles, 20 product-shaped protocol cycles, 0.0253 ms FileReader p95, 0.314 ms completion under a 64-timer backlog, queue high-water marks of one, and flat settled V8 heap.An exact clean SDK/package rebuild is running. Do not close #280/#252 or publish the PR until the unchanged-product first-paint rerun passes the 2-second bound. Evidence:
/private/tmp/vscode-demo-workspace-62c4c617.log; focused design:docs/validation/file-reader-single-task-20260921.mdon the candidate branch.wieslawsoltes commentedon Sep 21, 2026
Exact transport attribution after WebSocket per-socket fairness (#888) narrows the remaining #280/#252 breach to same-socket binary-message processing.
Exact input:
cd0a02ecd15f0a635bccc242cdd657888db39e252f3ff02a8fef7b6dd5cfa5fd07a532e850902639on merged main2b29eed6645f29cc3176500b4b5762ba887cf2a7f0ffdf2cThe functional oracle remains exact: remote root/provider, five resolved children, five model children, five visible Explorer rows, and 64 Explorer DOM nodes. Resolve is 980.58–981.00 ms. First paint is 2,061.06–2,078.14 ms, narrowly above the 2 s gate.
Opt-in metadata-only native tracing records socket id, event type, byte count, enqueue/dispatch times, queue delay, and remaining events; it never records payload content. Relative to the second-document observer:
This proves #888 removed cross-socket head-of-line blocking. The worker loop also already avoids layout/scene publication when these protocol tasks leave the document unchanged. The next focused implementation is the binary WebSocket → Blob → FileReader path. WebScene's Blob constructor currently stringifies every input part eagerly for a nonstandard
toString()cache; stringifying a 262 KiBUint8Arraycreates a large comma-separated decimal string even when no caller requests text. That work repeats across the 11.87 MB startup stream and is absent from browser Blob construction.Next change: make Blob's compatibility string representation lazy while preserving its current observable result, add a large binary Blob/WebSocket regression and bounded construction benchmark, then rerun this exact package gate. Keep #280/#252 open until first paint is below 2 s.
Evidence:
/private/tmp/vscode-demo-workspace-2f3ff02a-trace.log,/private/tmp/vscode-demo-workspace-2f3ff02a-trace-evidence/logs/server.log, and/private/tmp/vscode-demo-workspace-2f3ff02a-graceful.log.wieslawsoltes commentedon Sep 21, 2026
Exact merged-package closure evidence — 21 September 2026
The current installed-SDK Release now passes the shared unchanged-product gate that this issue was waiting for.
Exact inputs:
cd0a02ecd15f0a635bccc242cdd657888db39e25a99eaf23aef5e5525b0a58c5635fa8a431b604f1645f29cc3176500b4b5762ba887cf2a7f0ffdf2c475c5652aed411cb98867ad79074e75096534adce6f607cbe1a11f5b2b39ab9b9c3404b01537cca336717492030f548b15180fc5c3d1f684185963808d430b4fc78d19651bf5615b9db7595ea2aa16bc252ad1395d19b83b610088639c864fc2Unchanged-product result:
.hidden.txt,readme-link,README.md,subdir,unicodé.txt;The closing implementation chain is merged: shared task-source/protocol fairness, dedicated FileReader scheduling, per-socket WebSocket fairness (#888), metadata-only diagnostics (#889), and lazy binary Blob compatibility-string expansion (#890, merge
a99eaf23). The 12 MiB focused Blob gate measured 0.867 ms construction without requested text expansion versus 55.79 ms with explicit expansion (~64.4×), preserved the exact snapshot/string result, retained cross-socket ordering, and finished with flat settled heap.The wider workspace/watcher/dependent-service matrix remains tracked by #252. This issue's shared implementation and exact-product latency gate are complete.
wieslawsoltes commentedon Sep 21, 2026
Reopened after repeated exact-package run — 21 September 2026
The first exact merged-package run passed at 1,880.02 ms, but a second independent cold run on the same AppScene cd0a02e / WebScene a99eaf2 / unchanged Code OSS 645f29cc package painted at 2,179.19 ms. Provider resolve remained bounded at 1,110.87 ms, the exact root/provider/five resolved/model/rendered children remained correct, and maximum Explorer DOM nodes remained 64.
Because this issue explicitly requires the unchanged-product first-child result within two seconds across repeated cold/warm qualification, one passing run is insufficient. The issue is reopened pending a multi-cycle p50/p95 gate and attribution of the remaining approximately 179 ms breach. The already merged direct scheduler/Blob regressions remain valid and are not reverted.
wieslawsoltes commentedon Sep 21, 2026
Repeated native qualification on exact merged inputs WebScene
a99eaf23, AppScenecd0a02e, unchanged Code OSS645f29cc:I tested a bounded worker task-batch change from 4 ms to 8 ms. It preserved exact functionality but regressed paint to 2,219.65 ms p50 / 2,337.72 ms p95 / 2,361.70 ms max and 8/20 passes. The candidate was discarded and was not committed or published.
The next implementation must target the actual management-channel queue or repeated cascade/layout publication boundary, while retaining the 4 ms task batch and the existing input/resize/render opportunities.
wieslawsoltes commentedon Sep 21, 2026
A second targeted candidate removed the intermediate
Uint8Arrayand JavaScriptslice()for WebSocketbinaryType="arraybuffer"delivery.The focused WebSocket/FileReader suite passed: exact Blob and ArrayBuffer bytes, 100 cross-source fairness cycles, settled heap, protocol timing, and FileReader ordering. The unchanged-product 20-launch gate did not improve:
The candidate was discarded without a commit or PR. This rules out the ArrayBuffer conversion copy as the owner of the bimodal delay. Next work stays focused on protocol callback work and the layout/scene publication boundary.
wieslawsoltes commentedon Sep 21, 2026
Completed by the shared merged scheduler/protocol chain plus WebScene PR #891.
The exact unchanged-product qualification passed 20/20 launches with the requested root, provider, five resolved/model/rendered children, and first-child paint under 2 seconds. Resolve p95 is 762.64 ms and paint p95 is 1860.12 ms. Broader workspace-file, multi-root, interaction, visual, dependent-service, and lifecycle acceptance remains tracked in #252.