fix: close the CI-rebuild follow-ups (tag trust, playground double worker, WebGL2 particle texture) - #652
Merged
Merged
Conversation
added 7 commits
September 3, 2026 05:23
…ocally The pre-push hook's tag path ran the full verify:release suite, which repeated every lane CI had already run on the push that brought the commit to main and could still disagree with what the Release workflow accepts. scripts/ci/trust.ts now holds that decision once: the tag matches package.json, sits on origin/main and carries a green verdict. The workflow's trust job and the hook both run it, and verify:release, whose only caller was the hook, is gone. Claude-Session: https://claude.ai/code/session_01YRLzcQ9ZasLdUWCtD9fDpM
…ervices The editor mounted before the selected example was known, creating a throwaway model under a placeholder path in the pre-load default language (JavaScript); switching `path` afterwards left that model alive, so Monaco kept a JavaScript and a TypeScript language service and downloaded the 6.9 MB ts.worker chunk twice. With cacheable responses the second request failed with ERR_CACHE_WRITE_FAILURE against the entry the first was still writing, and the resulting Worker `error` event reached Monaco's unexpected error handler as a bare `Event` - the `Uncaught [object Event]` seen on a playground page's first load. Claude-Session: https://claude.ai/code/session_01YRLzcQ9ZasLdUWCtD9fDpM
`no-store` was covering for the playground booting two TypeScript language services and fetching the 6.9 MB ts.worker chunk twice, whose second request failed against the cache entry the first was still writing. That is fixed, so the harness can serve what a static host serves and exercise the browser cache visitors actually get. Claude-Session: https://claude.ai/code/session_01YRLzcQ9ZasLdUWCtD9fDpM
WebGl2ParticleRenderer bound the system texture only when its identity changed, which for a scene with a single particle system meant exactly once - while the handle from `loader.get(...)` was still an empty placeholder. The image landed a few frames later and bumped the texture version, but nothing ever asked the backend to look again, so the system kept drawing its quads against blank pixels for the rest of its life. Scenes with two systems on different textures alternated the identity every frame and were healed by accident, which is why some particle examples rendered and others stayed black. The same memo could also hold a stale blend mode after another renderer changed it. Both are now offered to the backend on every system: it owns the live GL state, already collapses a redundant bind, and is the only place that sees a texture whose payload changed under a stable identity. Claude-Session: https://claude.ai/code/session_01YRLzcQ9ZasLdUWCtD9fDpM
… came up `app.backend` before `start()` is the requested backend, not the one that initialised: a WebGPU request that finds no adapter falls back to WebGL2 during startup. Read at module scope, the example therefore budgeted 320 000 particles at 75 000 per second onto the CPU integrator whenever WebGPU was requested and unavailable - sixteen times the fallback budget its own note describes. The choice moves into `init()`, which the scene director runs after the backend is settled. Claude-Session: https://claude.ai/code/session_01YRLzcQ9ZasLdUWCtD9fDpM
Both entries recorded the symptom of a renderer defect, not a limit of the environment: the WebGL2 particle renderer never re-bound a texture whose payload arrived after the first draw, which left every scene with a single particle system black on any WebGL2 path, software rasteriser or not. With that fixed, all six particle examples pass the harness under `--use-angle=swiftshader`, so the skips would only hide the next regression. The backend-comparison entry stays: that one is genuinely a throughput limit. Claude-Session: https://claude.ai/code/session_01YRLzcQ9ZasLdUWCtD9fDpM
Leaving out --enable-unsafe-webgpu no longer suppresses the adapter on current Chromium, so the WebGL2 lane ran with WebGPU present and never exercised the renderer path it exists for - which is how a WebGL2-only particle defect survived it. The lane now overrides navigator.gpu in every frame before any page script runs, for the probe and the pool. Claude-Session: https://claude.ai/code/session_01YRLzcQ9ZasLdUWCtD9fDpM
Exoridus
enabled auto-merge (squash)
September 3, 2026 03:36
Bundle ReportChanges will decrease total bundle size by 17.81MB (-36.63%) ⬇️. This is within the configured threshold ✅ Detailed changes
Affected Assets, Files, and Routes:view changes for bundle: exojs-particles-esmAssets Changed:
Files in
view changes for bundle: site-server-esmAssets Changed:
Files in
App Routes Affected:
view changes for bundle: exo-full-iife-Exo-iifeAssets Changed:
Files in
view changes for bundle: exo-full-iife-min-Exo-iifeAssets Changed:
Files in
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes the follow-ups left open by the CI rebuild.
Release admission
scripts/ci/trust.tsholds the tag admission rule once: the tag matchespackage.json, sits onorigin/main, and carries a greenverdict. The Release workflow'strustjob and the pre-push hook's tag path both run it, so a tag the workflow would reject is rejected before it leaves the machine.verify:release, whose only caller was the hook's tag path, is removed.Playground
pathafterwards left that model alive, so Monaco kept a JavaScript and a TypeScript language service and downloaded the 6.9 MBts.workerchunk twice; with cacheable responses the second request failed withERR_CACHE_WRITE_FAILUREagainst the entry the first was still writing, and the Workererrorevent surfaced asUncaught [object Event]. The editor is now withheld until the example is known.Particles
WebGl2ParticleRendererbound a system's texture only when its identity changed, which for a single-system scene meant exactly once, while the handle fromloader.get(...)was still empty. The image landed a few frames later and never reached the GPU, so every single-system particle example stayed blank on WebGL2 (any WebGL2 run without WebGPU, real GPU included, not only SwiftShader). Texture and blend mode are now offered to the backend on every system. Two pixel-readback browser tests cover a late payload and an in-place texture edit.gpu-particlesreadapp.backendbeforestart()and budgeted 320 000 particles onto the CPU integrator whenever WebGPU was requested but unavailable; the read moved intoinit().Smoke harness
--renderer webgl2now overridesnavigator.gpuin every frame before page scripts run. Leaving out--enable-unsafe-webgpuno longer withholds the adapter on current Chromium, so the CI WebGL2 lane had been running with WebGPU present.Verification
node scripts/ci/trust.ts v0.16.1green; a bogus tag and a wrong main ref fail with the expected messages; hook probed via stdin for both.--renderer webgl2 --only particles/: adapter reportedno, 6 passed. Smoke--only getting-startedwith cacheable responses: 3 passed, no shell errors. Under--use-angle=swiftshaderthe particle category went from 2 passed / 4 failed to 6 passed.verify:quickand every lane.https://claude.ai/code/session_01YRLzcQ9ZasLdUWCtD9fDpM