Repository navigation
feat: M6 - WASM depth inference in a module Web Worker - #12
Merged
Merged
Conversation
On the WASM fallback the ONNX session blocked the main thread ~4-11s per
pass (M4 finding). Inference now runs in a dedicated module worker
(src/depth-worker.js); the WebGPU path is byte-identical. The
split-by-device design keeps the webInitChain poison structurally
impossible: worker inits only wasm, main thread only webgpu.
Bridge: canvas -> ImageData (buffer transferred) -> worker RawImage ->
depth posted back as plain {data,width,height}. Both call sites now pass
a canvas (photo handler draws its ImageBitmap instead of a blob URL).
timeEstimator wraps the proxy, so the M5 readout measures the real round
trip; the fake-estimator seam stays main-thread. Worker init failure or
crash rejects in-flight passes and clears the estimator cache for retry.
Verified from installed transformers.js 4.2.0 source before coding:
DedicatedWorkerGlobalScope is a supported env; RawImage(data,w,h,channels)
is a plain field-assignment constructor exported from the root.
Test M6-A pins the photo-path canvas input (RED pre-M6: blob-URL string).
Real-model probe (headless, WASM, worker): 38.2s pass rendered 558 rAF
frames, max gap 1.57s — pre-M6 the gap was the whole pass.
Autopilot: STATUS.md M6 (Web Worker WASM inference)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Capture the owning promise at load time, not at worker-ready time, so a stale load failure or worker crash can never clear a cache entry it does not own (e.g. a test-installed fake swapped in mid-load). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Task
STATUS.md Milestone 6 — Web Worker WASM inference (human-approved 2026-07-03; effort gate explicitly bypassed by the user this session). On the WASM fallback the ONNX session blocked the main thread ~4–11s per pass (M4 finding); inference now runs in a dedicated module worker so orbit stays live during a pass. The WebGPU pipeline path is unchanged (it already computes off-thread); splitting by device keeps the
webInitChainpoison structurally impossible (worker inits only wasm, main thread only webgpu).Design
src/depth-worker.js: init loadspipeline('depth-estimation', …, {device:'wasm'}); per pass wraps posted ImageData pixels inRawImage(data,w,h,4)and posts back plain{data,width,height}depth. Facts verified from the installed 4.2.0 source before coding:DedicatedWorkerGlobalScopeis a supported env (env.jsIS_WEBWORKER_ENV);RawImageis root-exported with a plain field-assignment constructor.src/depth.js: worker bridge with id-paired pending map; input buffer transferred, result cloned (we don't own the library buffer). Worker init failure or crash rejects in-flight passes, terminates, and clears the estimator cache (identity-guarded) so retry spawns a fresh worker.src/main.js: photo handler hands the estimator a canvas (drawn from its ImageBitmap) instead of a blob URL — the one input type valid on both paths.timeEstimatorwraps the proxy, so the M5 readout measures the true round trip; the__setEstimatorfake seam stays main-thread; M4 gen-token/drop-never-queue machinery untouched.RED test
M6-A pins the photo-path canvas input contract. Proven non-tautological: the byte-identical test ran RED against pre-M6 production code (estimator received a blob-URL string), turned green with only production edits.
Real-model probe (throwaway, deleted)
Headless → WASM → worker: a 38.2s pass rendered 558 rAF frames, max gap 1.57s (pre-M6 the gap was the whole pass). WASM device note shown, M5 readout reported the round trip, depth applied, no errors.
Verifier
One independent adversarial verifier (failure-paths/bridge-lifecycle lens): PASS — could not refute (ran full suite 13/13). Its one closeable finding (cache-reset identity captured too late, test-seam-only clobber risk) is fixed in
398e08d. Remaining notes accepted: hung-worker class pre-exists M6; result clone is perf-only.Review
Inline single-pass review: no unresolved findings.
Full local suite: 13/13 green. Rollback (pre-change HEAD):
c61d33b.Autopilot: STATUS.md M6 (Web Worker WASM inference)
🤖 Generated with Claude Code