# Reported deep-view artifact investigation and fix Date: 2026-09-29 ## Purpose Investigate the reported URL state that displayed large yellow/black geometric regions and sometimes an almost entirely black frame. The production source before this pass is preserved as `index.before.html`. The fix is intentionally narrow: do not restore previously removed expensive work unless evidence points to it. Reported state: - bits: 273 - re: `-15958919693715511752069626580195447581643016686947107473855747766272418724092005269` - im: `3884297345146583343999140717464554120497735725078805729405733239132420430333375719` - span: `35679807704506851074208413824041445358585910697267232113437882789120793` - palette: 0 - cycle: 0.008 - shift: 0.18 - base iteration: 350, adaptive enabled, quality high At 1108×1582, the adaptive initial target for this region is approximately 1536 iterations and the renderer takes the `fast-extended` path. ## Root cause 1: unsafe series jump The integrated fourth-order series approximation was enabled for the reported view. The fast-reference worker selected: - reference pixel ≈ `(69.5, 922.5)` - reference length: 1285 - series jump: 773 - fourth-order coefficient components up to approximately `2.35e38`, close to the maximum finite f32 magnitude The series validity test checked truncation terms in unscaled orbit space, but did not bound the *intermediate scaled f32 polynomial products* used by WGSL. At screen-domain deltas away from the selected reference, `a4 * d^4` can overflow before the later `ldexp` rescales the term. The reproducible probe in `experiments/reported-view/analyze.mjs` evaluates the exact worker output from the preserved pre-fix source. On a 32×32 viewport sample grid: - pre-fix: 290 / 1024 series starts produce a non-finite fourth-order intermediate - fixed: 0 / 1024, because series acceleration is disabled This is sufficient to generate `RANGE` failures and black unknown pixels. Separate CPU surrogate comparison also showed large escape-iteration deviations in this state, so merely adding an overflow clamp would not make the current jump trustworthy enough for publication. ### Fix `SERIES_APPROXIMATION_ENABLED=false` now disables production series construction. The code remains present for future work, but the fast-reference worker emits `jump=0` and zero coefficients. Re-enabling series should require at minimum: 1. viewport/reference-relative bounds on all scaled polynomial intermediates, 2. a propagated truncation/rounding error bound carried into the perturbation path, 3. a corpus test that checks false escapes, not only absolute approximation error, 4. strict handling when the selected reference is off-center. ## Root cause 2: publishing numerical failures before repair The FAST primary frame was colored and presented immediately after the primary perturbation pass, before `recoverNumericalCostOrdered()` repaired `REFERENCE_END`, `RANGE`, and other numerical failures. `COLOR_WGSL` writes alpha zero for `FIELD_UNKNOWN`. Therefore an early provisional frame can appear: - black when there is no usable history, - mixed with reprojected old colors when stable history exists, - as large geometric regions reflecting reference validity / numerical-failure domains rather than Mandelbrot geometry. ### Fix For `fast-extended`: - primary colorization is deferred (`deferPrimaryColor = deferColor || fastExtended`), - unresolved statistics are read, - numerical failures are repaired, - only then is the first provisional recolor/presentation allowed. Direct rendering keeps its existing provisional behavior. ## What was *not* reverted The previous FAST coverage-repair dispatch was not restored. The existing full-frame unknown reduction and final invariant still detect untouched reason-0 pixels, and prior A/B coverage tests found no holes. The reported state produced a concrete series failure mechanism, so restoring an O(pixels) repair pass would treat the symptom without addressing the cause. Other removal-pass optimizations are unchanged. ## Verification ### Regression `node tests/regression.mjs` Result: PASS, 19 WGSL kernels. Additional regression pins were added for: - `SERIES_APPROXIMATION_ENABLED=false` - FAST primary-color deferral via `deferPrimaryColor=deferColor||fastExtended` ### Reported-view worker probe `node experiments/reported-view/analyze.mjs` See `results.json`. Key result: | Metric | Before | After | |---|---:|---:| | reference length | 1285 | 1285 | | series jump | 773 | 0 | | non-finite series-start samples | 290 / 1024 | 0 / 1024 | ### Existing integrated CPU benchmark `node experiments/integrated_bench.mjs` Completed successfully. The series section now reports jump 0 at all tested spans, while periodicity, sparse active state, multi-reference, and CPU fallback tests continue to run. ### Browser/WebGPU smoke `tests/browser_smoke.mjs` could not run because its expected external Chromium remote-debug endpoint at `127.0.0.1:9333` was not available in this environment. This is an environment limitation, not a test assertion failure. Actual WebGPU visual confirmation of the supplied URL remains the most important local-device check. ## Build summary See `build-summary.json`. - before SHA-256: `e69b91ead027927d977a065d27d9e27629110122df20aa470eab877e23f77ac7` - fixed SHA-256: `c53c0dc4cb9fa2d2046aaa12ef03cc79c61a710b0c8db36dea1a87be2d9aedd8` - HTML size delta: +396 bytes (comments/guard and publication-order logic) The WGSL kernels themselves were not changed in this pass, so kernel hashes remain pinned to the prior 19-kernel set.