// Independent localhost control plane and real Windows browser. No cloud/model downloads. import assert from 'node:assert/strict'; import {createRequire} from 'node:module'; import {createServer} from 'node:http'; import {mkdtempSync,mkdirSync,existsSync,writeFileSync} from 'node:fs'; import {tmpdir} from 'node:os'; import {join,resolve} from 'node:path'; import {spawn} from 'node:child_process'; import {randomBytes} from 'node:crypto'; import {createApp} from '../apps/server/app.mjs'; import {openStore,digest} from '../apps/server/store.mjs'; import {inspect,verifyPolicy} from '../packages/core/policy.mjs'; const require=createRequire(import.meta.url),electron=require('electron'); const temporary=mkdtempSync(join(tmpdir(),'safetynet-semantic-browser-')); const runtime=resolve('.runtime/windows/semantic'),python=resolve('.runtime/windows/python/python.exe'); assert.ok(existsSync(join(runtime,'models/model-manifest.json')),'Stage verified local model artifacts before running'); const fixtures={reference:'Confidential corporate restructuring will close the Lisbon office next autumn and eliminate two hundred positions before the public announcement. Leadership is negotiating a six-million-euro acquisition of a rival. These undisclosed staffing reductions and acquisition plans are restricted internal company information.',paraphrase:'Private workforce planning calls for shutting the Portugal branch after summer and cutting roughly two hundred jobs. Executives are discussing a six-million-euro purchase of a competitor; the timetable and personnel reductions remain undisclosed.',publicText:'A simple tomato pasta recipe combines ripe tomatoes, olive oil, garlic and fresh basil. Boil the pasta in salted water and serve it warm.'}; let inspector,management,sink,store,child; const report={model:'google/embeddinggemma-2',revision:'bfcd298762cc34d0357ece5ebdd31791a3a374d8',dimensions:768,profile:'document-v1',artifactFormat:'gguf',quantization:'Q8_0',runtimeRevision:'b11461',local:true}; try{ const inspectorToken=randomBytes(32).toString('base64url'),adminToken=randomBytes(32).toString('base64url'),code=randomBytes(32).toString('base64url'); inspector=spawn(python,['apps/inspector/server.py'],{windowsHide:true,stdio:['ignore','pipe','pipe'],env:{...process.env,EMBEDDING_MODEL_DIR:join(runtime,'models'),EMBEDDING_WORKER_PATH:join(runtime,'searchi-gemma-worker.exe'),INSPECTOR_TOKEN:inspectorToken,INSPECTOR_PORT:'0',INSPECTOR_PARENT_PID:String(process.pid)}}); inspector.stderr.on('data',()=>{}); const inspectorPort=await new Promise((accept,reject)=>{let output='';const timeout=setTimeout(()=>{inspector.kill();reject(Error('Inspector startup timed out'));},40000);inspector.once('error',reject);inspector.once('exit',()=>{clearTimeout(timeout);reject(Error('Inspector exited before startup'));});inspector.stdout.on('data',chunk=>{output+=chunk;if(output.includes('\n')){clearTimeout(timeout);try{accept(JSON.parse(output.split('\n')[0]).port);}catch{reject(Error('Invalid inspector startup'));}}});}); sink=createServer((_req,res)=>{res.setHeader('Content-Type','text/html');res.end('Local semantic enforcement fixture

Public browser fixture

');}).listen(0,'127.0.0.1');await new Promise(resolve=>sink.once('listening',resolve));
  store=openStore(join(temporary,'management.sqlite'));
  const initial=store.get('policy');initial.browser.homeUrl=`http://127.0.0.1:${sink.address().port}`;initial.browser.allowedHosts=['127.0.0.1'];initial.dlp.rules=[];store.put('policy',initial);
  store.db.prepare('INSERT INTO enrollments VALUES(?,?,?)').run(digest(code),Date.now()+600000,'synthetic-semantic-user');
  const config={publicUrl:'http://127.0.0.1',secure:false,adminToken,inspectorUrl:`http://127.0.0.1:${inspectorPort}`,inspectorToken};
  management=createApp(store,config).listen(0,'127.0.0.1');await new Promise(resolve=>management.once('listening',resolve));config.publicUrl=`http://127.0.0.1:${management.address().port}`;
  async function admin(route,body,method='POST'){const result=await fetch(config.publicUrl+route,{method,headers:{authorization:`Bearer ${adminToken}`,'content-type':'application/json'},body:JSON.stringify(body),signal:AbortSignal.timeout(90000)});assert.equal(result.status,200,`Central route ${route} failed`);return result.json();}
  const teaching=await admin('/api/admin/teaching',{label:'Synthetic confidential workforce plan',filename:'synthetic-reference.txt',data:Buffer.from(fixtures.reference).toString('base64')});
  await admin(`/api/admin/teaching/${teaching.id}/publish`,{expectedVersion:initial.version,approve:true});
  const reference=await admin('/api/admin/semantic/reference',{description:fixtures.reference});
  for(const key of ['model','revision','dimensions','profile','artifactFormat','quantization','runtimeRevision','local'])assert.equal(reference[key],report[key],`Unexpected local model ${key}`);
  const policy=store.get('policy');policy.version++;policy.dlp.semantic={enabled:true,model:reference.model,revision:reference.revision,dimensions:reference.dimensions,profile:reference.profile,artifactFormat:reference.artifactFormat,quantization:reference.quantization,runtimeRevision:reference.runtimeRevision,categories:[{id:'synthetic-restructuring',label:'Synthetic restricted workforce plan',threshold:0.65,prototype:reference.vector,prototypes:reference.vectors}]};
  assert.equal(inspect(Buffer.from(fixtures.paraphrase),policy).decision,'allow','Paraphrase accidentally matches a deterministic rule');
  const secret=await admin('/api/admin/policy/test',{text:fixtures.paraphrase,policy}),ordinary=await admin('/api/admin/policy/test',{text:fixtures.publicText,policy});
  assert.equal(secret.ruleId,'synthetic-restructuring','Semantic paraphrase did not match calibrated category');assert.equal(ordinary.decision,'allow','Unrelated public text failed semantic calibration');
  await admin('/api/admin/policy',policy,'PUT');const signed=verifyPolicy(store.envelope(),store.publicKey());assert.equal(signed.dlp.semantic.revision,report.revision);assert.equal(signed.dlp.semantic.profile,report.profile);
  const env={...process.env,SAFETYNET_SEMANTIC_PROFILE:join(temporary,'browser'),SAFETYNET_SEMANTIC_SERVER:config.publicUrl,SAFETYNET_SEMANTIC_CODE:code,SAFETYNET_SEMANTIC_ADMIN:adminToken,SAFETYNET_SEMANTIC_FIXTURES:JSON.stringify(fixtures)};
  // Prove the browser's automatic bundled-path wiring rather than the fixture inspector environment.
  delete env.EMBEDDING_MODEL_DIR;delete env.EMBEDDING_WORKER_PATH;delete env.ELECTRON_RUN_AS_NODE;
  child=spawn(electron,['scripts/semantic-browser-smoke.cjs'],{windowsHide:true,stdio:'inherit',env});const timer=setTimeout(()=>child.kill(),100000);
  const status=await new Promise(resolve=>{child.once('exit',code=>resolve(code??1));child.once('error',()=>resolve(1));});clearTimeout(timer);assert.equal(status,0,'Native semantic browser fixture failed');
  Object.assign(report,{centralTeaching:true,signedPolicyVerified:true,deterministicParaphraseAllow:true,semanticParaphraseBlock:true,publicTextAllow:true,paraphraseSimilarity:secret.similarity?.[0]?.score,publicSimilarity:ordinary.similarity?.[0]?.score,nativeProofPassed:true});
  mkdirSync('artifacts',{recursive:true});writeFileSync('artifacts/semantic-browser-proof.json',JSON.stringify(report,null,2));console.log(JSON.stringify(report));
}finally{
  child?.kill();inspector?.kill();for(const server of [management,sink])if(server){server.closeAllConnections();await new Promise(resolve=>server.close(resolve));}store?.db.close();
}