import fs from 'node:fs'; import path from 'node:path'; import crypto from 'node:crypto'; const read=p=>JSON.parse(fs.readFileSync(p,'utf8').replace(/^\uFEFF/,'')); const hash=p=>crypto.createHash('sha256').update(fs.readFileSync(p)).digest('hex'); const state=read('C:/laragon/data/sgf-tempo/run/modular-regression-current.json'),tag=process.argv[2]; if(state.port!==55439||!/^[a-f0-9]{12}$/.test(tag||''))throw Error('Owned QA tag required'); const root=path.join(state.root,'private/payable-history-'+tag),basic=read(path.join(root,'regression.json')),pages=read(path.join(root,'page-cases.json')),http=read(path.join(root,'page-http.json')),fresh=read(path.join(root,'page-fresh-command.json')),concurrent=read(path.join(root,'page-concurrent-read.json')),positive=read(path.join(root,'page-filter-positive.json')),post=read(path.join(root,'page-post.json')); if(basic.cases.some(c=>!c.passed)||pages.cases.some(c=>!c.passed)||!http.passed||!fresh.passed||!concurrent.passed||!positive.passed||!post.original_workflow_receipt_unchanged||!post.temporary_decision_and_allocation_tables_absent)throw Error('Current evidence incomplete'); const archive=path.join(root,'page-post.json.'+hash(path.join(root,'page-post.json'))+'.archive'); if(!fs.existsSync(archive)||read(archive).scoped_business_fingerprint!==post.scoped_business_fingerprint)throw Error('Read/negative-test final business fingerprint changed'); const comparisons=[]; for(const volume of [1000,5000,10000]){ const legacy=read(path.join(root,`bench-${volume}-legacy.json`)); for(const size of [25,100]){ const current=read(path.join(root,`bench-${volume}-page${size}.json`)); if(legacy.position_fingerprints[size]!==current.position_fingerprints[size]||legacy.php!==current.php||legacy.memory_limit!==current.memory_limit||legacy.indices_added||current.indices_added||current.rows.documents!==size||current.queries!==67)throw Error('Measurement parity or conditions differ'); comparisons.push({volume,page_size:size,before:{time_ms:legacy.time_ms,queries:legacy.queries,php_heap_peak_bytes:legacy.php_heap_peak_bytes,php_heap_extra_peak_bytes:legacy.php_heap_extra_peak_bytes,documents_returned:legacy.rows.documents},after:{time_ms:current.time_ms,queries:current.queries,php_heap_peak_bytes:current.php_heap_peak_bytes,php_heap_extra_peak_bytes:current.php_heap_extra_peak_bytes,documents_returned:current.rows.documents},financial_position_fingerprint:current.position_fingerprints[size],source_hashes:{legacy:hash(path.join(root,`bench-${volume}-legacy.json`)),current:hash(path.join(root,`bench-${volume}-page${size}.json`))}}); } } const attrs=t=>Object.fromEntries([...t.matchAll(/(\w+)="([^"]*)"/g)].map(m=>[m[1],m[2]])); const selected=new Map();const nativeFiles=['private/stock-receipt-879a40eff72c/financial-read-affected-junit.xml','private/stock-receipt-efcf1053aa57/financial-read-affected-junit.xml']; const nativeProofs=nativeFiles.map(name=>{const p=path.join(state.root,name),xml=fs.readFileSync(p,'utf8');let passing=0,excluded=0;for(const m of xml.matchAll(/]*\/>|]*>[\s\S]*?<\/testcase>/g)){const c=attrs(m[0].match(/^]*>/)[0]);if(/<(?:failure|error|skipped)\b/.test(m[0])){excluded++;continue;}selected.set(c.name,{name:c.name,assertions:Number(c.assertions),proof:name});passing++;}return {file:name,sha256:hash(p),passing_cases:passing,excluded_cases:excluded};}); if(selected.size!==21)throw Error('Native compatibility cases incomplete'); const previous=read('docs/proofs/module-association-http-lock-summary-20261102.json');for(const p of [previous.proof,...previous.previous_proofs])if(hash(p.path)!==p.sha256)throw Error('Earlier association evidence changed'); const files=['packages/payables/src/Payables.php','packages/payables/src/HistoricalPayments.php','packages/payables/src/PaymentDecisions.php','packages/payables/src/SupplierSettlements.php','packages/payables/ui/page.php','app/Modules/Purchasing/SupplierPayables.php','app/Modules/Purchasing/SupplierHistoryReceipts.php','app/Modules/Purchasing/SupplierPayablesController.php','config/supplier_payable_history.php','../compras/tests/Feature/PayableHistoryImportTest.php']; files.push(...['payable-page-run.mjs','payable-page-fixture.php','payable-page-cases.php','payable-page-bench.php','payable-page-load.mjs','payable-page-http.mjs','payable-page-final.php','summarize-payable-page.mjs','payable-history-sgf-proof.php','stock-receipt-composition.mjs'].map(f=>'scripts/'+f)); if(!fs.readFileSync('config/supplier_payable_history.php','utf8').includes("'synthetic_enabled' => false"))throw Error('Historical capability unexpectedly activated'); const report={date:'2026-11-02',increment:'SGF-PAYABLE-PAGED-READ-SIM-v1',status:'local_synthetic_implementation', verification:{sgf_existing_history_scenarios:basic.tests,sgf_existing_history_assertions:basic.assertions,sgf_new_page_scenarios:pages.scenarios,sgf_new_page_assertions:pages.assertions,native_distinct_compatibility_tests:selected.size,native_assertions:[...selected.values()].reduce((n,c)=>n+c.assertions,0),actual_paging_http_checks:http.checks}, comparisons, measurement_conditions:{php:'8.4.27',memory_limit:'512M',same_owned_database_per_volume:true,independent_php_process_per_strategy:true,warmup:'Same bounded source search in every worker; database seeded/warm; no cache flush. Legacy runs first, followed by page25/page100.',samples_per_strategy:1,legacy_measurement_reused_for_both_page_sizes:true,legacy_baseline:'Existing integral core listing plus original scoped source callbacks; includes all document/evidence rows. Does not include the old adapter post-listing permission flags. New measurement includes the full paged SGF adapter.',memory:'PHP allocated heap peak in independent workers, including 24 MiB framework baseline. Extra zero means reuse of existing allocation, not zero memory use. Not OS RSS.',index_experiments_performed:false,indices_added_or_removed:false,gain_attribution:'Combined bounded pagination, batch dependent reads and removal of writer locks from reads; not an isolated estimate for each technique. No index gain claimed.',no_deployment_capacity_claim:true}, functional_pages:pages,existing_history_regression:basic,http,fresh_command:fresh,concurrent_read:concurrent,positive_recognition_and_unit_filter:positive,postcheck:post, private_proof_sha256:Object.fromEntries(['regression.json','page-cases.json','http-proof.json','page-http.json','page-fresh-command.json','page-concurrent-read.json','page-filter-positive.json','page-post.json'].map(f=>[f,hash(path.join(root,f))])), native_compatibility:{proofs:nativeProofs,selected_cases:[...selected.values()],selection:'20 valid cases reused from initial run; one test fixed to wrap expected PostgreSQL trigger violations in savepoints and rerun alone in a fresh QA database. Intermediate failed cases are retained but not counted. A reused RefreshDatabase fixture was refused by duplicate-function setup; launcher now requires a new owned database for this mode.'}, implementation:{documents_page_sizes:[25,100],proposal_and_event_pages_independent:true,filters_applied_before_pagination:['number_or_supplier_literal_search','recognised_or_unrecognised'],stable_order:'Documents/proposals/events descending ID; obligation positions keep existing ID order.',history_and_allocation_algorithms_reused:true,write_paths_never_use_read_snapshots:true,actual_read_transaction:'REPEATABLE READ READ ONLY',no_company_writer_lock_on_read:true,native_production_adapter_unchanged:true}, source_sha256:Object.fromEntries(files.map(f=>[f,hash(f)])), reused_proofs:Object.fromEntries(['docs/proofs/sgf-payable-history-receipt-20261102.json','docs/proofs/workshop-stock-closure-20261102.json','docs/proofs/native-warehouse-return-20261102.json'].map(f=>[f,hash(f)])), preservation:{new_owned_qa_databases_only:true,one_actual_native_workflow_source_plus_explicit_benchmark_clones:true,previous_native_and_sgf_history_fixtures_preserved:true,six_pending_associations_untouched:true,blocked_cache_untouched:true,installed_and_demo_data_or_rights_unchanged:true,no_new_operational_migration_or_indices:true,publication:false,purchasing_activation:false,checkpoint:false}, limits:['A page includes the complete dependency history needed to validate each selected obligation; an unusually large single history still needs separate assessment.','Pagination snapshots are per request, not a fixed snapshot across human navigation or keyset cursor.','The standalone native adapter retains its old listing; compatibility was tested against the canonical package in private QA, not deployed to native/demos.','Read timings are local, warm, single samples; no concurrency throughput, production capacity or visual acceptance established.','Historical receipts remain synthetic snapshots; no live provenance authentication or operational financial-responsibility cutover added.'],visual_review_pending:true,deployment_capacity_validated:false}; fs.writeFileSync('docs/proofs/sgf-payable-paged-read-20261102.json',JSON.stringify(report,null,2)+'\n');console.log(JSON.stringify({verification:report.verification,comparisons:report.comparisons.map(c=>({volume:c.volume,page:c.page_size,before_ms:c.before.time_ms,after_ms:c.after.time_ms,before_queries:c.before.queries,after_queries:c.after.queries,before_peak_MiB:c.before.php_heap_peak_bytes/1048576,after_peak_MiB:c.after.php_heap_peak_bytes/1048576}))},null,2));