Repository navigation
Description
Parent epic: #264. Top-level release epic: #227.
Proven gap
At VS Code OSS 645f29c, browser/pre/index.html requires navigator.serviceWorker, registers service-worker.js as a module, waits for controllerchange, calls registration.update(), and exchanges messages with the controller. Markdown Preview does not set disableServiceWorker. WebScene b81f594c explicitly reports navigator.serviceWorker unsupported (WEBSCENE1001) and has no ServiceWorker binding. Once #253 stops the earlier synchronous iframe exception, this is the next deterministic initialization failure.
This focused issue owns the control plane: ServiceWorkerContainer, module-worker registration/update, install/activate, skipWaiting, clients.claim, controller selection/change, Client/WindowClient identity and postMessage, controlled-document generations, failure reporting, unregister, navigation, and teardown. The resource/stream/cache plane is a separate dependent child.
Dependencies and boundaries
- Depends on Expose HTMLIFrameElement.sandbox for Code OSS webviews and Markdown Preview #253 for the unchanged outer iframe to reach the prelude.
- Reuses Implement Worker, transferable MessagePort, and iframe contexts for Code OSS #81 worker task ownership, transferable MessagePort, structured clone, and bounded queues; Implement Worker, transferable MessagePort, and iframe contexts for Code OSS #81 retains its MessagePort prototype and extension-host acceptance.
- Coordinates with AppScene#31, [GPU 12/20] Implement cross-canvas snapshots and real PNG/Blob pixel export #34, [GPU 14/20] Implement native WebGL 1 bindings and ANGLE browser semantics #36, and [GPU 19/20] Qualify WebGPU/WebGL conformance, resilience and support claims #41. No AppScene-specific service worker shim or VS Code patch is acceptable.
- Publish a Code OSS Web API capability ledger and expand WPT coverage #263 owns the release-wide API/WPT ledger and Qualify all unchanged Code OSS workbench commands, panels, and feature lifecycles #260 owns the full workbench matrix; this issue supplies their focused service-worker evidence.
- Does not include PR Optimize structural CSS invalidation and DOM mutation checkpoints #245 files or CSS work.
Acceptance
- IDL descriptors, brand checks, secure-context visibility, registration matching, update, install/waiting/active state, events, controller selection, Clients
get/matchAll,postMessage,skipWaiting,claim, unregister, errors, and Promise timing match selected Service Worker WPTs and Chromium. - A native top-level + iframe fixture proves a module service worker controls only admitted same-origin clients, survives the required reload transition, rejects cross-origin/sandbox-opaque access, and never adopts a stale navigation generation.
- The exact VS Code prelude reaches
webview-readyand obtains its expected controller without source changes. - 100 register/control/update/unregister cycles leave zero worker runtimes, clients, event listeners, ports, tasks, and registrations after teardown; no timing sleep determines correctness.
- Cold register-to-controller p95 <= 1 s and warm controlled-navigation p95 <= 250 ms on the recorded macOS CI reference; the 100-cycle fixture retains <= 8 MiB after warm-up and publishes task/queue high-water counts.
- macOS arm64, Linux x64, Windows x64 native and installed-consumer lanes pass.
Proposed PR stack
- IDL/state store and registration matching;
- module worker lifecycle and controller/Clients semantics;
- navigation/security/teardown and WPT/browser oracle;
- unchanged VS Code prelude acceptance and performance evidence.
Active status — 17 September 2026
PRs #276/#278 merged at 053a5627/aa786c0e. Exact stamped Code 645f29c reaches the version-6 controller and logs webview ready after 2.665 s. The issue remains open because cumulative PR #281 is conflicted with current main and its current-main 100-cycle gate exposes active MessagePort listener collection in #288/PR #245. Requalify and merge #281 before completing this issue or starting #266 implementation.
Activity
wieslawsoltes commentedon Sep 17, 2026
Stack C is visible as draft #281, based on #278. Its direct native/Chrome gates pass; the unchanged Markdown product gate remains red for a proven consumer/package reason outside that patch.
The exact clean-run nested document URL was:
https://109fs6ggj4valu0kc7igovsvgcpkgfl7fc4ol18kjhko1sf9nni0.vscode-cdn.net/insider/ef65ac1ba57f57f2a3961bfe94aa20481caca4c6/out/vs/workbench/contrib/webview/browser/pre/index.html?...&swVersion=6&...Fresh network captures of those exact CDN assets show:
index.html: SHA-256cbdc558190c89f95610a3fa4c8c1732e2d077de9214cf24e318e3bb927902daf; its lines 233-250 listen for{ channel: 'version' }, compare the returned value to queryswVersion, and emit the observed reload log;service-worker.js: SHA-25699de3b00d51d8143cbea53b9eade42c64b2b0259a4630deb065712b8033b61e3; it declaresVERSION=4and replies with{ channel: 'version', version: VERSION }.The exact package and unchanged consumer source both select that stale endpoint in
server/product.json:38/vendor/vscode/product.json:38. The current Code OSS645f29cworkbench expects service-worker version 6. The adjacentappscene-host-request kind=4line is request-kind telemetry and is not the protocol version.Before #281 becomes ready, the product lane must correct the packaged webview endpoint, rerun with isolated Code and AppScene/WebScene cache roots, and prove the exact unchanged Markdown preview renders. AppScene currently forwards only
compilation_cache_directoryfromAPPSCENE_WEBSCENE_CACHE_DIRECTORY; it does not configure WebScenestorage_directory, which separately explains the same run's missing globalindexedDB.wieslawsoltes commentedon Sep 17, 2026
Corrected fresh-cache product gate (Stack C
031ed8c5)The unchanged-Code Markdown gate remains red. I ran a copied fixture and fresh Code profile plus fresh
APPSCENE_WEBSCENE_CACHE_DIRECTORY, with the Stack C dylib, and closed all processes afterward.Evidence:
README.mdSHA-256db3dd0a4483949b325f267734c2c58ab3101e04853f2d202e182ecbf51471cb8(from unchanged vscode-demoHEAD:README.md). The current README contains local Markdown links but no image syntax, so there is no current image payload to validate./private/tmp/webscene-265-current-evidence.TQ33pF/markdown-preview.png. The wrapped text is the left source editor, not preview output./private/tmp/webscene-265-current-evidence.TQ33pF/app.stderr.log, lines 924-927. The nested document still used/insider/ef65ac1ba57f57f2a3961bfe94aa20481caca4c6/..., loggedFound unexpected service worker version. Found: 4. Expected: 6, thenAttempting to reload service worker;webview readyfollowed 115 ms later. A malformed image resource request failed about 1.2 s later.vwas accidentally inserted only into the copied fixture while invoking the chord. The fixture was restored afterward to the SHA above; the shared vscode-demo workspace was never edited by this run.The stale endpoint is now traced to the built Code artifacts, not WebScene cache/storage:
product.jsondoes contain the exact-head645f29cc3176500b4b5762ba887cf2a7f0ffdf2cCDN template.out/server-main.js(line 442) andout/vs/code/browser/workbench/workbench.js(lines 439 and 1023) both embedef65ac1...and contain no645f29c..../private/tmp/webscene-265-product-probe.cpbl7T/root.htmlconfirms the server sends only a minimal product override, so the browser workbench retains its compiled stale template.Therefore fresh Code/WebScene storage cannot make this retained package an exact-head product oracle. A rebuilt package whose generated bundles embed
645f29c...is required before Stack C can be marked ready. This does not identify an additional WebScene implementation defect; PR #281 remains draft pending that corrected product gate.wieslawsoltes commentedon Sep 17, 2026
Stamped exact-head product boundary — control plane passes
The stale-package variable is removed. I reran unchanged Code OSS against
/private/tmp/webscene-265-stamped-server, whose retained stamp evidence proves all three generated bundles contain645f29cc3176500b4b5762ba887cf2a7f0ffdf2c, contain zeroef65ac1...occurrences, and ship the exact current v6 prelude/worker hashes.Run isolation and fixture:
/private/tmp/webscene-265-stamped-profile.2jQsvyAPPSCENE_WEBSCENE_CACHE_DIRECTORY:/private/tmp/webscene-265-stamped-cache.tZwEnvvscode-demo/README.md: SHA-256db3dd0a4483949b325f267734c2c58ab3101e04853f2d202e182ecbf51471cb8031ed8c5Result for this issue's boundary:
Found unexpected service worker versionor reload message;workerReadycontroller gate;Webview(739f08ec-adbf-46a4-a3e4-413a58a941ca): webview ready;will update content: 653 ms; content update → ready: 2,012 ms; command → ready: 2,665 ms.Exact compact events:
/private/tmp/webscene-265-stamped-run.A3t8FO/product-gate-events.json. Full diagnostic log:app3.stderr.log. Screenshot:preview-stamped.png. Final app RSS was 328,368 KiB. All app/server/helper processes were terminated and the copied/shared README hashes remained unchanged.This proves the #265 control plane reaches its unchanged-product boundary. The full Markdown preview remains blank for the dependent #266 resource plane: Markdown leaves its body empty until extension
pre.jsand styles arrive throughwebview.asWebviewUri(...), which requires Service WorkerFetchEvent, Streams, and CacheStorage. Stack C deliberately does not implement those APIs. The first observed post-ready failure is a malformed CSS-derived image URL; that independent CSS escape defect is being filed separately and must not be folded into #265.The retained direct gates remain: native/Chrome Clients 3/3, controlled navigation generation, bounded 256-message/16 MiB queues, 100-message p95 0.095 ms, and 100 lifecycle cycles p95 4.23 ms with zero final registrations.
wieslawsoltes commentedon Sep 17, 2026
Current-main integration gate: held by #288 / #245
Bottom stack entries #276 and #278 are merged. Retargeting this tranche onto current
mainproduced one scheduler conflict, resolved by preserving Service Worker reply delivery and #285's Worker/MessagePort/WebSocket rotation. The combined native build passes the 100-cycle Service Worker lifecycle gate, but the unchanged 100-cycle Clients/MessagePort gate exposes a pre-existing active-port garbage-collection defect around cycle 69–70.The old #281 build passes. Applying #245 commit
94171a32locally is insufficient because it covers local peer reachability, while this case requires a started port with an installed handler to stay active across GC. Diagnostic replacement ofport.onmessage = resolvewith an extra closure makes 5/5 runs pass; that is evidence only and is not being committed as a workaround.The focused gap is #288, linked under #81. Its implementation path overlaps owner-controlled #245, so this PR remains open until #245 supplies the active-port lifetime fix and the cumulative Service Worker lifecycle/Clients plus WebSocket gates pass on current
main. No #245 path is being changed here.