import fs from 'node:fs';import path from 'node:path';import crypto from 'node:crypto';import assert from 'node:assert/strict'; const [readTag,demoTag]=process.argv.slice(2);for(const t of [readTag,demoTag])assert(/^[a-f0-9]{12}$/.test(t??'')); const run=JSON.parse(fs.readFileSync('C:/laragon/data/sgf-tempo/run/modular-regression-current.json')),base=path.join(run.root,'private'),readRoot=path.join(base,'stock-trace-read-'+readTag),demoRoot=path.join(base,'receipt-composition-'+demoTag),prior=path.join(base,'receipt-composition-f9cc0b003f44/app'),read=p=>JSON.parse(fs.readFileSync(p,'utf8')),hash=p=>crypto.createHash('sha256').update(fs.readFileSync(p)).digest('hex'); const tests={};for(const [name,root,file,count]of [['read',readRoot,'stock-trace-read-result.json',16],['ui',readRoot,'stock-trace-ui.json',20],['demo',demoRoot,'stock-trace-demo.json',10]]){const p=path.join(root,file),r=read(p);assert(r.passed);assert.equal(r.checks.length,count);tests[name]={file:'private/'+path.basename(root)+'/'+file,sha256:hash(p),checks:count,result:r};} assert.deepEqual(tests.read.result.before,tests.read.result.after);assert.equal(tests.read.result.valid_prefix_reused,14); const sources=['app/Modules/Purchasing/StockReceiptTraceController.php','app/Modules/Inventory/CompositionStockRead.php','routes/web.php','config/receipt_qa.php','resources/js/app.jsx','resources/js/stock-receipt-trace.js','resources/js/StockReadWorkspace.jsx','resources/js/StockMenuWorkspace.jsx','public/purchasing-focus.mjs','public/stock-receipt-focus.mjs','public/receipt-workspace.mjs']; for(const root of [readRoot,demoRoot])for(const file of sources)assert.equal(hash(file),hash(path.join(root,'app',file)),file); const unchanged=['app/Modules/Purchasing/ReceiptController.php','app/Modules/Purchasing/ReceiptRuntime.php','packages/inventory-read/src/InventoryReader.php','packages/inventory-read/src/InventoryReadSession.php','resources/js/context-transition.js','app/Modules/Identity/Services/IdentityWorkflow.php','app/Shared/Context/ModuleNavigation.php'];for(const file of unchanged)assert.equal(hash(file),hash(path.join(prior,file)),file); const extract=s=>s.slice(s.indexOf(' const navigate ='),s.indexOf(' async function api('));assert.equal(extract(fs.readFileSync('resources/js/app.jsx','utf8')),extract(fs.readFileSync(path.join(prior,'resources/js/app.jsx'),'utf8'))); const pins={};for(const dir of ['bundle','economic','internal']){pins[dir]=hash(path.join(demoRoot,dir,'manifest.json'));for(const [file,h]of Object.entries(read(path.join(demoRoot,dir,'manifest.json')).files))assert.equal(hash(path.join(demoRoot,dir,file)),h);}assert.deepEqual(pins,read('docs/proofs/stock-composed-source-20261103.json').pinned_native_manifests); const previous=['docs/proofs/stock-composed-source-20261103.json','docs/proofs/purchasing-focus-composition-20261103.json','docs/proofs/module-association-consolidation-summary-20261102.json'].map(file=>({file,sha256:hash(file)})),assoc=read(previous[2].file);assert.equal(hash('app/Modules/Identity/Services/ModuleAssociationReview.php'),assoc.source_sha256);assert.equal(hash('app/Modules/Identity/Http/ModuleRecordsController.php'),assoc.controller_sha256);assert.equal(hash('packages/purchasing/current.json'),read(previous[0].file).preservation.installed_purchasing_sha256); const manifest='public/build/manifest.json',entry=read(manifest)['resources/js/app.jsx'].file;assert.equal(hash(manifest),hash(path.join(demoRoot,'app',manifest)));assert.equal(hash('public/build/'+entry),hash(path.join(demoRoot,'app/public/build',entry))); const out='docs/proofs/stock-receipt-trace-20261103.json';assert(!fs.existsSync(out));fs.writeFileSync(out,JSON.stringify({date:new Date().toISOString(),increment:'SGF-STOCK-RECEIPT-TRACE-QA-v1',passed:true,functional_code:true,checks:46,tests,sources:sources.map(file=>({file,sha256:hash(file)})),unchanged_authority:unchanged.map(file=>({file,sha256:hash(file)})),accepted_navigation_function_unchanged:true,pinned_native_manifests:pins,build:{manifest_sha256:hash(manifest),entry_sha256:hash('public/build/'+entry)},demo:{port:8084,entry:'http://127.0.0.1:8084/qa/enter/validator?module=stock&open=1',navigate:'Stock > Existências > Movimentos > Conferir recepção em Compras',initial_main_requests:0,initial_receipts:0,initial_movements:0},prior_proofs_preserved:previous,preservation:{installed_purchasing_sha256:hash('packages/purchasing/current.json'),new_permission_names:[],new_real_grants:false,stock_reader_grants_widened:false,reused_host_tables:31,reused_native_tables:111,reused_business_commands:0,target_database_connected:false,protected_six_records_changed:false,blocked_cache_cleared:false,previous_demo_data_written:false,publication:false,checkpoint:false},limitations:['The resolver is only for receipt_in movements created by the current writer with a consistent receipt_id. Historical unlinked movements and other movement kinds are not inferred.','The Stock SELECT-only connection remains limited to three tables. Receipt resolution uses the existing authorised Purchasing runtime and its locking model, not the Stock technical reader.','Existing 14 backend assertions are reused after fixing object-identity comparison in the preservation harness. The additional suffix observes both APIs and proves31 host/111 native tables and sequences unchanged. No business source setup is replayed.','20 UI checks use helper calls, actual React component rendering/callback and simulated DOM startup. No browser visual proof or unsaved-form acceptance is claimed.','The fresh demo verifies a real context-selection POST and renewed token with one existing context audit, then refuses an unknown origin. Its book starts empty; the positive receipt correlation is proved in the read-only overlay of the completed QA book.','A demo harness initially queried an incorrectly named audit table; corrected to identity_audit before testing the actual module transition. No business operation was issued.','No new movement, payment, valuation, ledger entry, operational installation, sustained-load or deployment-capacity validation.'],visual_review_pending:true,deployment_capacity_validated:false},null,2)+'\n');console.log(JSON.stringify({output:out,checks:46,demo_port:8084}));