import assert from 'node:assert/strict'; import fsSync from 'node:fs'; import fs from 'node:fs/promises'; import vm from 'node:vm'; import {createHash} from 'node:crypto'; const prodUrl=new URL('../index.html',import.meta.url); const prodHtml=await fs.readFile(prodUrl,'utf8'); const extract=html=>[...html.matchAll(/]*>([\s\S]*?)<\/script>/g)].map(m=>m[1]); const prodScripts=extract(prodHtml); assert.equal(prodScripts.length,2); for(const script of prodScripts)new vm.Script(script); // Production is the single source of truth. No copied test HTML is allowed. assert.equal(fsSync.existsSync(new URL('./index.test.html',import.meta.url)),false); assert.doesNotMatch(prodHtml,/TEST_MODE|__MANDEL_TEST__|\bruntime\b|generationMetric|activeBatchLimit/); assert.doesNotMatch(prodHtml,/truestate|returnfinishRenderClock/); // Removed legacy/dead subsystems and stale diagnostics must not creep back. for(const pattern of [ /DEEP_PERTURB/,/FAILURE_TILE_MAP_WGSL/,/DEEP_COMPACT_(?:INIT|CONTINUE)_WGSL/, /referenceCandidates\(/,/refinePixelFrontierLegacy/,/refinePixelFrontierFinite/, /pixelFrontierIterationFloor/,/prefetchFinalReference/,/readMetaAll/,/readFieldAll/, /renderTileMeta/,/isOperationLimitMeta/,/readUnresolved\(/, /numericRecoveryPending|numericRecoveryRunning|qualityFinalIter|qualityStage/, /adaptiveProbeScorer|guidedReferenceScorer/, /\bFIELD_INTERIOR_LIKELY\b/,/function fromDec\(/,/function decimalRequiredBits\(/, /state\.(?:lastEngine|frontierRounds|frontierPixels|frontierEscaped|frontierIter|frontierMinimumIter|frontierConverged|gpuUnavailable|qualityIter|refineMs|lastRender|gpuStage)/, /this\.(?:adapterInfo|compilation|uncapturedErrors)/, /cpuFrameRgba/,/fast-coverage-repair/,/mode 2 repairs only untouched coverage holes/ ]) assert.doesNotMatch(prodHtml,pattern,String(pattern)); // Pin the surviving kernels. const kc={};vm.runInNewContext(prodScripts[0],kc);const kernels=kc.MANDEL_WEBGPU_KERNELS; assert.equal(Object.keys(kernels).length,20,'19 WGSL kernels + version'); const expected=JSON.parse(await fs.readFile(new URL('./kernel_hashes.json',import.meta.url),'utf8')); const hashes=Object.fromEntries(Object.entries(kernels).map(([k,v])=>[k,createHash('sha256').update(v).digest('hex')])); assert.deepEqual(hashes,expected); assert.doesNotMatch(kernels.COLOR_WGSL,/reason\s*==\s*6u[^}]*interior_color/s); assert.match(kernels.COLOR_WGSL,/Finite-budget survivors are unresolved membership/); assert.match(kernels.COLOR_WGSL,/textureStore\(outTex,vec2\(gid\.xy\),vec4\(0\.0\)\)/); assert.match(kernels.DIRECT_F32_WGSL,/candPeriod/); assert.match(kernels.DIRECT_F32_WGSL,/FIELD_INTERIOR_HEURISTIC/); assert.doesNotMatch(kernels.FAST_PERTURB_WGSL,/pack_meta\(n,FIELD_INTERIOR_HEURISTIC\)/); assert.match(kernels.FAST_PERTURB_WGSL,/series_start/); assert.match(prodHtml,/SERIES_APPROXIMATION_ENABLED=false/); assert.match(prodHtml,/deferPrimaryColor=deferColor\|\|fastExtended/); assert.doesNotMatch(kernels.FAST_PERTURB_WGSL,/unknownOnly==2u/); assert.match(prodHtml,/knownInteriorViewportMayOverlap/); assert.match(prodHtml,/numericHistoryScaleEligible/); assert.match(prodHtml,/ensureExportAaSamples/); assert.match(prodHtml,/exportWorkspaceDestroy\(\);exportJob\.active=false/); assert.match(kernels.DEEP_ACTIVE_CONTINUE_WGSL,/pixelMap/); assert.match(kernels.DEEP_ACTIVE_CONTINUE_WGSL,/states\[slot\]/); function appContext(){ const element={width:800,height:600,clientWidth:800,clientHeight:600,style:{},hidden:false,value:'',textContent:'',disabled:false,addEventListener(){},classList:{toggle(){}},setAttribute(){},removeAttribute(){},showModal(){},close(){},toBlob(){},getBoundingClientRect(){return{left:0,top:0,width:800,height:600}}}; let revoked=0; const context={ MANDEL_WEBGPU_KERNELS:kernels,document:{querySelector:()=>element,getElementById:()=>element,documentElement:{classList:{toggle(){}}},body:{classList:{toggle(){}},appendChild(){}}}, navigator:{hardwareConcurrency:4,deviceMemory:8},location:{search:'',hash:''},history:{replaceState(){}},performance, URLSearchParams,URL:{createObjectURL:()=>`blob:test-${Math.random()}`,revokeObjectURL:()=>{revoked++}}, TextEncoder,Blob:class{},console,addEventListener(){},requestAnimationFrame:()=>1,cancelAnimationFrame(){}, setTimeout,clearTimeout,setInterval,clearInterval,innerWidth:800,innerHeight:600,devicePixelRatio:1, localStorage:{getItem(){return null},setItem(){},removeItem(){}}, }; const cut=prodScripts[1].indexOf('// ── boot / teardown'); assert.ok(cut>0,'boot marker missing'); const code=prodScripts[1].slice(0,cut)+`\n`+ `globalThis.internal={state,refs,referenceScorer,fastRefs,precisionFallbackPool,ReferenceService,FastReferenceService,PrecisionFallbackService,WebGpuRenderer,chooseBackend,numericalFailureCount,pixelPrecisionBits,certifiedInteriorTiles,referenceWorkerSource,fastReferenceWorkerSource,precisionFallbackWorkerSource,adaptiveProbeChoice,adaptiveProbeSources,operationLimitReferenceEligible,failureGuidedReferenceEligible,tryOperationLimitGuidedReference,integerGridReuseShift,nearbyReferenceCandidates,refinePixelFrontier,fixedSourceForPixel,applyQuality,maxIter,buildExportMetadata,cancelRender,exportJob,renderFrame,cpuFallbackWorkerSource,recoverNumericalGuided};})();`; vm.runInNewContext(code,context); context.revoked=()=>revoked; return context; } function fromDec(s,bits=256){ s=String(s).trim();let neg=s.startsWith('-');if(neg)s=s.slice(1);if(s.startsWith('+'))s=s.slice(1); const [mant,es='0']=s.toLowerCase().split('e'),exp=parseInt(es,10)||0,[i='0',f='']=mant.split('.'); let digits=(i+f).replace(/^0+(?=\d)/,'')||'0',places=f.length-exp;if(places<0){digits+='0'.repeat(-places);places=0} const den=10n**BigInt(places),v=(BigInt(digits)*(1n<({active:5}),readUnresolvedStats:async()=>({total:5,reasons:{operationLimit:5}})}; const result=await a.refinePixelFrontier(r,snap,1024,7,{total:5,reasons:{operationLimit:5}}); assert.equal(result.finiteBudgetComplete,true);assert.equal(result.membershipCertified,false); } { Object.assign(a.state,{continuationBudget:1024,token:8});const snap={bits:256,re:0n,im:0n,span:fromDec('3.4')}; const r={beginGpuOperationLimitContinuation:async()=>({active:0}),readUnresolvedStats:async()=>({total:0,reasons:{operationLimit:0}})}; const result=await a.refinePixelFrontier(r,snap,1024,8,{total:0,reasons:{operationLimit:0}}); assert.equal(result.membershipCertified,true); } { Object.assign(a.state,{continuationBudget:1024,token:9});const snap={bits:256,re:0n,im:0n,span:fromDec('3.4')}; const r={beginGpuOperationLimitContinuation:async()=>({active:0}),readUnresolvedStats:async()=>({total:0,heuristicInterior:1,reasons:{operationLimit:0}})}; const result=await a.refinePixelFrontier(r,snap,1024,9,{total:0,heuristicInterior:1,reasons:{operationLimit:0}}); assert.equal(result.membershipCertified,false); } // The 12-point adaptive probe policy stays intact. { const snap={bits:256,re:0n,im:0n,span:fromDec('3.4')}; assert.equal(a.adaptiveProbeSources(snap,800,600).length,12); assert.equal(a.adaptiveProbeChoice(Array(12).fill(3000),3870,350).iter,3870); assert.equal(a.adaptiveProbeChoice(Array(12).fill(7000),3870,350).iter,350); } // Operation-limit scoring is staged: first 12, optionally second 12, one build. { Object.assign(a.state,{token:20,bits:256});const snap={bits:256,re:0n,im:0n,span:fromDec('3.4')},stats={reasons:{operationLimit:1000}},current={refLen:100}; const r={sampleActiveIndices:async()=>Uint32Array.from({length:24},(_,i)=>i)}; const oldScore=a.referenceScorer.scoreFixedCandidates,oldBuild=a.referenceScorer.requestFixed; let scores=0,builds=0; a.referenceScorer.scoreFixedCandidates=async()=>{scores++;return{winner:0,bestScore:300,precisionBits:160,scoreMs:1}}; a.referenceScorer.requestFixed=async(_s,_i,_w,_h,src)=>{builds++;return{refLen:300,checkpointMismatch:false,source:src,buildMs:1}}; let got=await a.tryOperationLimitGuidedReference(r,{},snap,300,20,stats,current,new Set()); assert.equal(got.used,true);assert.equal(got.usedSecond,false);assert.equal(scores,1);assert.equal(builds,1); scores=0;builds=0; a.referenceScorer.scoreFixedCandidates=async()=>{scores++;return scores===1?{winner:0,bestScore:180,precisionBits:160,scoreMs:1}:{winner:0,bestScore:250,precisionBits:160,scoreMs:1}}; a.referenceScorer.requestFixed=async(_s,_i,_w,_h,src)=>{builds++;return{refLen:250,checkpointMismatch:false,source:src,buildMs:1}}; got=await a.tryOperationLimitGuidedReference(r,{},snap,300,20,stats,current,new Set()); assert.equal(got.used,true);assert.equal(got.usedSecond,true);assert.equal(scores,2);assert.equal(builds,1); a.referenceScorer.scoreFixedCandidates=oldScore;a.referenceScorer.requestFixed=oldBuild; } // Exact certificates remain strict at cardioid/bulb boundaries. { const one=1n<<256n; for(const [re,expectedInside] of [[0n,true],[-one,true],[one/4n,false],[one/4n-1n,true],[-5n*one/4n,false],[-5n*one/4n+1n,true]]){ assert.equal(a.certifiedInteriorTiles({bits:256,re,im:0n,span:0n},1,1).pixels===1,expectedInside,re.toString()); } } // Stable integer-grid history reuse remains exact. { const bits=256,span=(1n<<240n)+12345n,old={bits,re:0n,im:0n,span,w:800,h:600},next={bits,re:-(span*40n)/800n,im:0n,span,w:800,h:600}; const shift=a.integerGridReuseShift(old,next,800,600);assert.ok(shift);assert.equal(shift.pixels,456000); assert.equal(a.integerGridReuseShift(old,{...next,re:-(span*81n)/1600n},800,600),null); } assert.match(a.nearbyReferenceCandidates.toString(),/deepContexts/,'GPU-resident guided refs participate in nearby reuse'); // Worker lifecycle: idle destroy still terminates/revokes resources. for(const Service of [a.FastReferenceService,a.PrecisionFallbackService]){ const s=new Service();let terminated=0;s.worker={terminate(){terminated++}};s.url='blob:idle';s.destroy();assert.equal(terminated,1);assert.equal(s.worker,null);assert.equal(s.url,''); } // Correction lazy compile contains only the five actually used pipelines. { const src=a.WebGpuRenderer.prototype.ensureCorrectionPipelines.toString(); for(const name of ['DEEP_BUCKET_HIST_WGSL','DEEP_BUCKET_PREFIX_WGSL','DEEP_BUCKET_SCATTER_WGSL','DEEP_CORRECT_WGSL','DEEP_CORRECT_QUEUE_WGSL'])assert.match(src,new RegExp(name)); assert.doesNotMatch(src,/DEEP_PERTURB/);assert.equal((src.match(/this\.module\(/g)||[]).length,5); } // Render cancellation must cancel export and advance the generation token. { Object.assign(a.state,{token:40,rendering:true,recolorPending:true,deferNumericPublish:true,renderClock:null});a.exportJob.active=true;a.exportJob.cancelled=false; a.cancelRender();assert.equal(a.exportJob.cancelled,true);assert.equal(a.state.token,41);assert.equal(a.state.rendering,false); a.exportJob.active=false; } // Both export paths share one metadata schema builder. { Object.assign(a.state,{adaptive:true,baseIter:350,unknownReasons:{operationLimit:7},fieldView:{backend:'pixel-frontier-fast-extended',membershipCertified:false,frontier:{finiteBudgetComplete:true,policy:'explicit-gpu-resident-finite-budget'}}}); const snap={bits:256,re:1n,im:2n,span:3n},palette={id:0,cycle:.008,shift:.18,edgeAA:false}; const completed=a.buildExportMetadata({snap,iter:4096,w:800,h:600,palette,completedField:true,exportPipeline:'completed-numeric-field'}); const rerender=a.buildExportMetadata({snap,iter:4096,w:1600,h:1200,ss:2,palette:{...palette,edgeAA:true},fastExtended:true,strict:true,unresolvedSamples:3,exportPipeline:'tiles',exportTileSize:128,exportRingDepth:1}); for(const key of ['format','rendererVersion','backend','numericEngine','finiteBudgetComplete','membershipCertified','precisionPolicy','pixelContract','width','height','supersampling','numericSamples','unresolvedSamples','iterationPolicy','view','palette','exportPipeline','shaderVersion']){assert.ok(key in completed,key);assert.ok(key in rerender,key)} assert.equal(completed.operationLimit,7);assert.equal(rerender.exportTileSize,128);assert.equal(rerender.exportRingDepth,1);assert.equal(rerender.membershipCertified,false); } // Run surviving CPU workers at tiny budgets. function worker(source,message){let result;const wc={self:{},postMessage:r=>{result=r},performance};vm.runInNewContext(source,wc);wc.self.onmessage({data:message});assert.ok(result);assert.notEqual(result.type,'error',result.error);return result} { const scale=1n<<256n,message={type:'build',id:1,key:'tiny',bits:256,sourceBits:256,targetBits:128,re:'0',im:'0',span:'0',width:1,height:1,iter:64}; const guarded=worker(a.referenceWorkerSource(),message),fast=worker(a.fastReferenceWorkerSource(),message); assert.equal(guarded.checkpointMismatch,false);assert.equal(guarded.refLen,64);assert.equal(fast.refLen,64);assert.deepEqual(Buffer.from(guarded.refs),Buffer.from(fast.refs)); assert.equal(fast.series.jump,0);assert.equal(fast.series.coeffs.length,8); const escaped=worker(a.precisionFallbackWorkerSource(),{type:'solve',id:2,bits:256,targetBits:128,re:(3n*scale).toString(),im:'0',span:'0',width:1,height:1,iter:64,terminalClass:-1,indices:Uint32Array.of(0).buffer}); assert.equal(new Uint8Array(escaped.accepted)[0],1);assert.equal(new Uint32Array(escaped.meta)[0]>>>28,1); const cpu=worker(a.cpuFallbackWorkerSource(),{type:'render',id:3,w:4,h:4,y0:0,y1:4,maxIter:64,re:-.5,im:0,span:3.4,style:{palette:0,cycle:1,shift:0}}); assert.equal(cpu.type,'done');assert.equal(new Uint8ClampedArray(cpu.rgba).length,4*4*4);assert.ok(cpu.work>0); } assert.match(a.recoverNumericalGuided.toString(),/FAILURE_GUIDED_REF_MAX_PASSES/); console.log('PASS: single-source finite viewer regression (production JS, 19 WGSL kernels, staged scoring, lifecycle, export metadata)');