# wasm-js-timing — VALIDATION RESULTS

## Signal hypothesis

WebAssembly numeric loops should run significantly faster than JS loops
(real browser WASM speedup is typically 5-15×). Headless Chrome or stealth
emulators may report inflated WASM speeds (50×+) due to debug-mode optimization
flags, or report deflated speeds (1-3×) due to missing WASM compiler optimizations.

## 2-test results (vanilla headless vs CDP-attached headless)

Both conditions: SUSPICIOUS (1 flag: WASM setter ratio <50×).

| Condition | WASM ops/sec | JS ops/sec | WASM/JS speedup | Verdict |
|---|---|---|---|---|
| Vanilla | 1000M | 71.4M | **14.00×** | 🟡 SUSPICIOUS |
| CDP | similar | similar | **2.00×** | 🟡 SUSPICIOUS |

**Same verdict (both SUSPICIOUS), wildly different magnitudes** (14× vs 2×).

## Analysis

The 14× speedup on vanilla is **real WASM** in a real Chrome instance.
The 2× speedup on CDP is **abnormally low** — WASM is barely faster than JS.
This suggests CDP attachment slows WASM execution by ~7× but barely affects JS.

The signal's threshold (50×) catches both, but the *underlying mechanism* is
different in each condition. The signal is sensitive to:
- WASM tier-up latency (CDP forces deopt)
- WASM compiler caching (CDP may invalidate)
- JIT optimization state (CDP disables some optimizations)

## Verdict: ⚠️ MARGINAL — useful but unreliable

The signal fires correctly in BOTH headless conditions, which is the right
behavior for a headless detector. But:
- Magnitude is unstable (14× → 2×) so absolute thresholds are unreliable
- Verdict is consistent across conditions (good)
- The 50× threshold is at the upper edge of expected variation

## Recommendation

Ship as a **soft Phase 3 signal** with conservative threshold: fire when
WASM/JS ratio < 5× OR > 50×. Use only when other behavioral signals are
ambiguous.

## Files

- `demo.html` — the spike page
- (no test.py — used `_generic_test.py` for validation)
