Repository navigation
Bound the packaged remote extension-host Ready-to-Initialized handshake #289
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: #81
Related downstream qualification: #280 and #252.
Adjacent but non-overlapping lifetime owner: #288.
Local diagnostic commit (not pushed): e6f5c6a in vscode-demo.
Proven boundary
An unchanged packaged Code OSS workspace run on WebScene base aa786c0e (with the local #287 measurement candidate 0f92cf47), AppScene 1420e227, Code OSS 645f29cc, and Node 24.18.1 retained every browser and native phase of extension-host startup.
The local iframe/Worker/transferred-MessagePort path completes promptly after its document is dispatched:
- iframe resource fetch: 0.835 ms, 6,786 bytes
- iframe append → document loaded: 1,189 ms
- document loaded → Worker created: 8 ms
- Worker created → transferred MessagePort: 130 ms
- transferred port → first message: 2 ms
- first port message → Ready: 1 ms
- local Ready → Initialized: 708 ms
- worker module resource fetch: 2.964 ms, 1,932,148 bytes
The remote extension-host path is the first distinct handshake breach:
- transport connected → first protocol byte / Ready: 1,177 ms
- Ready → Initialized: 4,379 ms
- remote Initialized → the separate AgentHost service connection: 9,682 ms
- AgentHost service connection → exact five-row Explorer result: 99 ms
The exact root, provider registration, five resolved children, five Explorer-model children, and five rendered rows all pass. The 2 s product bound fails. The run observed 146 FileReader reads / 13,120,521 bytes with a 14,767 ms maximum, while the underlying Blob conversion maximum was 0.038 ms. This points to delayed asynchronous protocol continuation rather than resource transfer or port transfer.
Observer bounds were 21/96 phase records with zero drops and 8/64 resource records. Peak app process-group RSS was 845,184 KiB. App/server/helper processes were terminated and verified absent after the bounded run.
Retained evidence:
/private/tmp/vscode-252-product-extension-host-81.log/private/tmp/vscode-252-extension-host-81-evidence.json(SHA-2561a53ca07dfa317aa7fdfcd6b598617e8cfd41105770e9ad7fe082dac1172e851)
Scope
Identify and fix the product-neutral scheduler/protocol boundary that delays the packaged remote extension host between connected transport, Ready, initialization-data delivery, and Initialized. Keep Code OSS source unchanged outside query-gated diagnostics.
This issue does not change MessagePort lifetime ownership in #288. That issue still owns forced-GC reachability; this trace shows the transferred port, first message, Ready, and Initialized all arrive in order.
Acceptance
- A reduced browser oracle and the native runtime retain timestamps for transport connected, first protocol byte, Ready, initialization-data send/settlement, Initialized, cancellation, reconnect, and teardown.
- Direct native/provider and unchanged Chromium runs distinguish socket receive, runtime task delivery, Promise/microtask continuation, protocol dispatch, and init-data serialization/handling.
- Cold and warm runs keep transport → Ready and Ready → Initialized each within 500 ms p95, and the complete remote handshake within 1 s p95, across at least 20 cycles.
- Competing WebSocket, FileReader, Worker, MessagePort, timer, and microtask traffic remains fair; queue high-water and wake counts are retained and bounded.
- Cancellation before Ready, cancellation during init-data creation, reconnect, navigation, Worker termination, socket close, and engine teardown release callbacks, ports, queues, and wake registrations exactly once.
- The unchanged Code OSS exact-root/five-child/five-row Qualify remote workspace bootstrap, Explorer contents, and watcher refresh #252 gate completes within 2 s without polling or product behavior changes.
- V8 heap and RSS plateau after warm-up; no retained protocol buffers, tasks, ports, or documents remain after teardown.
- Directly related macOS/Linux/Windows native gates and the browser oracle pass.
Activity
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.jsonda9db1awieslawsoltes commentedon Sep 17, 2026
The actual browser WebSocket send boundary rejects the earlier wire-delay hypothesis and moves the earliest breach into the deferred Code OSS protocol-writer flush.
Exact second-document timestamps:
protocol.send(...)returned after init serialization at 1789659699540WebSocket.sendentered at 1789659703082: 3,542 ms laterWebSocket.sendreturned in 0.743 ms, withbufferedAmount0 before and afterbufferedAmount0Pinned Code OSS
ProtocolWriter._scheduleWriting()coalesces writes behind a zero-delay timer. This run shows that timer-backed flush, rather than JSON serialization, native WebSocket enqueue, loopback wire delivery, Node parsing, or extension scanning, owns nearly all of the Ready → Initialized breach.The product-shaped control now uses a 13-byte IPC header, 1,071,425-byte binary body, 200 competing 64 KiB inbound frames per cycle, a shared FileReader queue, and 20 cycles. Direct native send remains fast (outbound p95 1 ms, send return p95 0.708 ms, drain p95 0.004 ms, receive-queue HWM 199). A deferred flush under a single independently paced WebSocket source also remains fast (flush timer p95 0.019 ms). The remaining reduction must model the product's combined/coalesced protocol writer plus simultaneous Worker, MessagePort, and multiple WebSocket task sources; no runtime fix is proposed yet.
The bounded run reached exact root/provider/five-child/five-model/five-row evidence, terminated its process group, and left no app/server/extension-host descendants. Peak group RSS was 845,648 KiB.
Retained evidence:
/private/tmp/vscode-252-product-websocket-send-289.log(SHA-25652296aa1c97c11c8c696577e7a0cb0dd27e2605a4a9c8fe26ee8f225ddb64ef5)/private/tmp/vscode-252-product-websocket-send-289-server.log(SHA-2564b6c06cf87e5e709431486b64d5920ca76041821290d0bea93f5297f85411228)/private/tmp/vscode-252-product-websocket-send-289-process.txt/private/tmp/webscene-289-product-shape.log/private/tmp/webscene-289-paced-async-deferred-flush.log4c7c662wieslawsoltes commentedon Sep 17, 2026
The reduced multi-source oracle now proves that #289's Ready→Initialized breach is owned by generic timer-vs-async task fairness in #287.
On exact merged-#245 main
4040058e, the actual 13-byte framing + 1,071,425-byte initialization body waits 3,581.35 ms from ProtocolWriter's coalesced zero-delay timer to the realWebSocket.sendcall while Worker/MessagePort/WebSocket work remains ready and the FileReader queue ages. The send itself takes 0.743 ms in the retained product trace and Node receives it 5 ms later, so this is not a wire-delay or serialization defect.The identical 20-cycle oracle with the local #287 arbitration candidate passes at 0.1539 ms max / 0.0475 ms p95, with Initialized p95 12.27 ms. Chromium passes 45/45 with about 0.1 ms timer p95/max. Local combined implementation/oracle commit
26694871remains unpushed pending #281's four-source ServiceWorker rotation merge and rebase.Detailed counts, queue bounds, memory/work bounds, logs, and SHA-256 values are retained on #287.
wieslawsoltes commentedon Sep 17, 2026
Exact unchanged-Code product rejection after rebasing the reduced candidate onto WebScene main
1bd8596e3dc07a3281204504acad379eb1f6bc78(b75d37958ef7ce3f73a5b08de6b0516b0f8f57eb, local/unpushed):178966180324517896618037171789661804058(340.689 ms)1789661804066(8.786 ms, 1,071,424 bytes)1789661804067WebSocket.sendentered1789661807765(+3698 ms)bufferedAmount=01789661807949(Ready→Initialized ~4232 ms)The same candidate passes the reduced product-neutral oracle (exact-main max 3617.66 ms → candidate max 0.204 ms), but that arbitration is not sufficient in the packaged product. The remaining owner lies in another task tier before native
WebSocket.send; wire/server/receiver work is still fast once the send begins. No PR is being opened.The workspace reached the exact
vscode-remoteroot, resolved the expected five children, and rendered five Explorer rows, but the observer correctly reportedstatus=failedbecause the two-second performance contract was missed. Query-gated diagnostics only; unchanged Code OSS source. App/server/extension-host/watcher/agent descendants were terminated; port 54759 has no listener. App RSS at capture was 557,840 KiB and the observed process tree totaled 1,181,904 KiB.Evidence log:
/private/tmp/vscode-252-product-b75d3795.log, SHA-256f58b40413fe5dd30567d0d6a3d207b668fd07bea96b594aae9c5568509a38252.wieslawsoltes commentedon Sep 17, 2026
The focused #293 candidate
b485f6aapasses its 20-cycle reduced window-message/timer oracle (max 0.323 ms) but does not move the unchanged packaged-Code boundary: protocol-send request → nativeWebSocket.sendremains 3478 ms, followed by a 0.815 ms send and 0.857 ms microtask. Ready→Initialized remains ~4102 ms.This excludes the async-message group and
window.postMessageas sufficient owners. Another runtime tier before due timers, or the condition that makes the protocol writer's timer eligible, still owns the delay. No push/PR; draft #292 remains a path collision.Evidence and cleanup:
/private/tmp/vscode-252-product-b485f6aa.log, SHA-256cb9b7c5c843da4badc2b8c7e35c2850b41598c70b7510afce7c94bee5b5a2a26; all descendants terminated and port 56322 free.wieslawsoltes commentedon Sep 17, 2026
The corrected runtime-gated task-source trace changes the remaining owner and rejects the queue-arbitration candidates as sufficient fixes.
Exact packaged evidence
a50fd344;/private/tmp/vscode-252-task-arbitration-a50fd344.log;0e0ac7d890bc6fe664ed6efa3054919aff932cc38cc9a607d906db073aa495a6;timerId=1194, requested at 50 ms, fired 3,051.582 ms overdue;fetchtask held the runtime for 2,805.749 ms, followed bywindow-messagework for 236.403 ms;The active investigation now instruments
drain_fetch_taskresponse construction, settlement, and its promise/microtask continuation. The reduced native response/header/cookie oracle is sub-millisecond; one bounded packaged trace with both task-source and fetch-phase probes is scheduled. No scheduler candidate will be pushed unless it passes the unchanged packaged product gate.wieslawsoltes commentedon Sep 17, 2026
The corrected runtime-env-gated task/fetch trace isolates the remaining #289 owner to the promise continuation for built-in theme loading; it is no longer a scheduler/wire ambiguity.
For
extensions/theme-defaults/themes/light_vs.json(7,407 bytes, status 200):PerformMicrotaskCheckpoint: 2424.455 msThe corresponding 50 ms timer was overdue 2459.903 ms, attributed to fetch 2457.097 ms; async message was 0.034 ms, window message 0.107 ms, and platform pumping 0.002 ms. Protocol-send request → native send remained 3268 ms; native send 0.677 ms and its microtask 0.716 ms.
Browser semantics require the promise microtask checkpoint to complete before the next timer task, so queue arbitration must not preempt it. Opened focused downstream performance issue #297 for the theme continuation/DOM-CSS hot path; no runtime behavior change or scheduler PR is proposed from this trace.
Observer commits
a50fd344and7ad62971remain local/unpushed. Evidence:/private/tmp/vscode-252-fetch-phases-7ad62971.log, SHA-256d1feb5b7970d56298ee80c2a49228dfc3060c4663dec3a2249b09e77c4d98b72. Full descendant and port cleanup verified.wieslawsoltes commentedon Sep 18, 2026
Fresh exact-package confirmation from AppScene
f52fb46b/ WebScene348ea440/ unchanged Code OSS645f29cckeeps this issue ahead of reopened #252 and AppScene#131.The authoritative absolute-folder case selected the exact remote URI and opened the new document. In its retained console timeline:
Initializing/Connectingat approximately1789718069286;Connectedat1789718072002, about 2.716 s later;beta/visible.txtchild, but measured first-child paint was 4,594.3 ms against the 2-second Qualify remote workspace bootstrap, Explorer contents, and watcher refresh #252 gate.Picker dialog (1,376.1 ms), post-accept handoff (486.4 ms), exact URI/options, root/child semantics, observer p95 (0.625 ms), and descendant/port cleanup pass. Runtime counters retained 1,250 late timers / 209,700 ms aggregate lateness, 193 worker waits, 178 signalled wakes, and 15 timeout wakes. This supports the existing scheduler/protocol scope here and avoids a duplicate latency issue.
Order remains #289 fix and 20-cycle handshake gates → #252 first-child rerun → remaining AppScene#131 path matrix.
wieslawsoltes commentedon Sep 18, 2026
PR #347 now carries the focused current-main fix and regression gates.
Current-main baseline (
b29684224dd2a7bff8398b82821c2803de4d43f0) with the exact same product-shaped 20-cycle oracle fails as follows:Candidate
dfe8ba07ea7465f4d145ff47b77d9bcbfd53f801uses one task-source arbitration invariant: after any non-timer task wins while a timer is due, that timer runs before another observable task source can monopolize the loop. JavaScript task run-to-completion and the required microtask checkpoint remain unchanged.Four focused native runs pass:
Retained evidence:
/private/tmp/webscene-289-baseline.log, SHA-25603ba50b64502a441ed5b85afde115ed8ee6e0036f2ed4fe48104b2a3121fe9fa;/private/tmp/webscene-289-candidate-{1,2,3,4}.log, SHA-256553e034f2c4870e0b73f6a94246566a8ce689211ced1a9833caca537abaacf0f,429db81e458bc705cb1edbec2efbdf53afc0578dc2c72e680dad75ae8ce7d36d,7791e028e54805465adbf344f7feeead458ce4fe4143ead6c7fdfdef4bca4edc,d8f33570ae8ba7ba2ebd464f1a14c342f99d9870fa5c579a6f72955582ce6fbb;/private/tmp/webscene-289-native-wpt-d/results.json, SHA-25638e6ede21efbde11647d57aef9731e14e8cb2f3a5e405810be983131a21898ee.The earlier Chromium 45/45 control remains applicable to this same contract. I did not start another browser process because the host currently has a long-running shared Chrome instance and the isolated headless runner could not obtain a separate page target. PR CI owns the cross-platform native and portable source gates. Unchanged packaged Code OSS remains the downstream #252 qualification after merge.
wieslawsoltes commentedon Sep 18, 2026
Merged PR #347 on exact main
114f38e1.3d7cfebc296b6806bfbe29a5541fe1c6897f05ecdbd7351a88415d369ea322c692153474fb7a933cThe Windows package job remained blocked by the pre-existing MSVC
std::vector::containserrors in the untouched CSS cascade file; preceding main run35320520086has the identical four errors. That failure is not attributed to #347.This issue stays open until the downstream unchanged packaged Code OSS #252 run proves the remote AgentHost interval and exact first-child paint bounds on merge
dbd7351a.wieslawsoltes commentedon Sep 21, 2026
21 September 2026 retained transport evidence
The FileReader single-task candidate at
302e6d18removes the earlier 1,114 ms FileReader maximum (candidate range: 31–45 ms) while preserving the unchanged Code OSS exact workspace result. The best first-child paint is now 2,043 ms, so the remaining breach is separate.A retained app/server run isolates that breach:
17899522371251789952238161(+1,036 ms)1789952238977Readysend start/completion:1789952238978(~2.7 ms after extension-host process start)Ready:1789952239128(+150 ms after Node sent it; +967 ms after browser transport connection)1789952239136Initialized:1789952239533WebScene native transport currently places events from every WebSocket in one global FIFO. Bulk management/protocol traffic on one socket can therefore sit ahead of the one-byte
Readymessage on a separate socket. The next implementation will preserve FIFO within each socket and round-robin ready sockets, with a two-socket regression proving bounded delivery under a saturated peer.Retained local evidence:
/private/tmp/vscode-demo-workspace-302e6d18-server-evidence/app.log/private/tmp/vscode-demo-workspace-302e6d18-server-evidence/code-oss-appscene-test-D5CE215F-BDE8-4DD5-95EE-1D6C29548748/logs/server.logwieslawsoltes commentedon Sep 21, 2026
Exact
ae37b204package result and remaining ownerThe per-socket fairness candidate passes its direct 128-frame/two-socket regression and the complete focused WebSocket/FileReader gate. The exact clean SDK also passes integrity/profile verification and AppScene 31/31 host tests.
The unchanged Code OSS five-child run remains functionally green but exceeds the product bound:
Retained browser/server timestamps reattribute the remaining handshake interval:
1789953112791Readysent:1789953113655Ready:1789953113699Node sends
Ready2.85 ms after the extension-host process begins its instrumented entry point, and WebScene dispatches it 44 ms later. The 864 ms before Node protocol startup is cold extension-host process launch/bootstrap, not incoming WebSocket dispatch. Browser init serialization then takes 10.92 ms; Node receives init 204 ms later, parses/hydrates in 5.36 ms, and emitsInitializedimmediately.PR #888 (once created) removes the independently proven cross-socket head-of-line mode. Keep #289 open for the remaining cold transport/process-start and outbound-init delivery bounds rather than attributing those intervals to FileReader or incoming socket FIFO.
Retained local evidence:
/private/tmp/vscode-demo-workspace-ae37b204-run2.log/private/tmp/vscode-demo-workspace-ae37b204-server-evidence/logs/server.logwieslawsoltes 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
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.