32 lines
7.1 KiB
JavaScript
32 lines
7.1 KiB
JavaScript
import fs from 'node:fs';import path from 'node:path';import crypto from 'node:crypto';import {spawnSync} from 'node:child_process';
|
|
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');if(state.port!==55439||!/^[a-f0-9]{12}$/.test(state.id))throw Error('Wrong QA host');
|
|
const attrs=t=>Object.fromEntries([...t.matchAll(/(\w+)="([^"]*)"/g)].map(m=>[m[1],m[2]]));const selected=new Map();
|
|
const runs=['workshop-stock-1793634406841.xml','workshop-stock-1793634619557.xml','workshop-stock-1793634796037.xml','workshop-stock-1793634950240.xml'];
|
|
const proofs=runs.map(name=>{const file=path.join(state.root,name),xml=fs.readFileSync(file,'utf8'),suite=attrs(xml.match(/<testsuite\b[^>]*>/)[0]);if(Number(suite.errors)||Number(suite.failures)||Number(suite.skipped))throw Error('Run not wholly passing');
|
|
const cases=[...xml.matchAll(/<testcase\b[^>]*\/>|<testcase\b[^>]*>[\s\S]*?<\/testcase>/g)].map(m=>attrs(m[0].match(/^<testcase\b[^>]*>/)[0]));if(cases.length!==Number(suite.tests))throw Error('Case count differs');
|
|
for(const c of cases)selected.set(c.name,{name:c.name,assertions:Number(c.assertions),proof:name});return {file:name,sha256:hash(file),tests:Number(suite.tests),assertions:Number(suite.assertions),errors:0,failures:0};});
|
|
const artifact='../compras/packages/inventory-return/releases/0.1.0',manifest=read(artifact+'/manifest.json');
|
|
if(hash(artifact+'/manifest.json')!=='2850a4f5cb678acfe3a9dbc7a7d62eb233bc72722ad0de374681c2679c90557c')throw Error('Return artifact changed');
|
|
for(const [f,sha] of Object.entries(manifest.files))if(hash(artifact+'/'+f)!==sha||hash('packages/inventory-return/'+f)!==sha)throw Error('Canonical return writer/artifact mismatch');
|
|
const native=read('docs/proofs/workshop-stock-20261102.json');for(const f of ['../compras/app/Services/StockIssueMovement.php','../compras/app/Services/StockWorkflow.php'])if(hash(f)!==native.source_sha256[f])throw Error('Native issue host changed since valid proof');
|
|
for(const [f,sha] of Object.entries(native.package.files))if(hash('packages/inventory-issue/'+f)!==sha)throw Error('Issue primitive changed');
|
|
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('Association proof changed');
|
|
const load=read('docs/proofs/stock-read-load-20261102.json');if(hash('packages/inventory-read/src/InventoryReader.php')!==load.source_sha256)throw Error('Reader changed since load proof');
|
|
const post=spawnSync('C:/laragon/tools/sgf-tempo/php-8.4.27/php.exe',['scripts/workshop-stock-state.php'],{encoding:'utf8',windowsHide:true});if(post.status!==0)throw Error('Rights/source restoration postcheck failed');
|
|
const files=['app/Modules/Workshop/WorkshopStock.php','app/Modules/Workshop/Http/WorkshopStockController.php','resources/js/WorkshopStockWorkspace.jsx','tests/Feature/WorkshopStockTest.php','tests/Support/workshop-stock-worker.php','packages/inventory-return/src/DeliveryReturnWriter.php','routes/web.php'];
|
|
const ui='docs/proofs/workshop-material-cycle-ui-20261102.json';const report={date:'2026-11-02',increment:'WORKSHOP-MATERIAL-CYCLE-SIM-v1',status:'local_synthetic_implementation',proofs,
|
|
selection:'Latest passing evidence selected per test name; repeated affected cases are not counted twice. Earlier intermediate failure is excluded. Later warehouse receipt declaration, history controls and ordered opening-stock timestamp were verified only in affected cases.',
|
|
totals:{distinct_tests:selected.size,assertions:[...selected.values()].reduce((n,c)=>n+c.assertions,0)},selected_cases:[...selected.values()],
|
|
scenario_asserted:{opening_milli:'10000',delivered_milli:'5000',physical_after_issue:'5000',consumed_allocation_milli:'2000',physical_after_allocation:'5000',returned_milli:'3000',physical_after_return:'8000',unallocated_after_return:'0',total_movements:3,original_issue_unchanged:true,opening_entry_precedes_issue:true,stock_read_sees_same_book:true,explicit_warehouse_receipt_required:true,service_and_writer_replay_original_return:true},
|
|
partial_allocations_asserted:{multiple_origins_one_delivery:true,quantity_bound_by_delivery:true,physical_effect_zero:true,stale_remaining_refused:true,already_allocated_origin_not_consumed_again:true,disabling_capability_does_not_erase_history_protection:true,failure_atomic_and_retry_once:true},
|
|
return_asserted:{consumed_client_unverified_unrepresentable_and_excess_refused:true,stale_capacity_refused:true,independent_confirmation_required:true,missing_receiving_declaration_422:true,right_revoked_403:true,stale_context_409:true,other_company_403_and_empty_history:true,decision_failure_rolls_back_movement_and_operation:true},
|
|
concurrency_asserted:{processes:2,company_row_blocker_observed_with_pg_blocking_pids:true,competing_allocations_3_plus_3_against_5:'first associates 3; second after release refuses 409',competing_returns_3_plus_3_against_5:'one positive movement of 3; second after release refuses 409'},
|
|
history_asserted:{server_page_size:25,proposal_fixture_count:51,descending_id_order:true,pages_disjoint:true,status_filters:['all','pending','confirmed'],confirmed_includes_allocations_and_returns:true,unknown_parameters_refused:true,tenant_company_unit_isolation:true},
|
|
package:{...manifest,manifest_sha256:hash(artifact+'/manifest.json'),canonical_identical:true,native_return_command_integrated:false},source_sha256:Object.fromEntries(files.map(f=>[f,hash(f)])),qa_postcheck:JSON.parse(post.stdout),
|
|
ui:{path:ui,sha256:hash(ui),...read(ui)},build:{passed:true,node:'24.22.1',vite:'8.3.5',manifest_sha256:hash('public/build/manifest.json')},
|
|
reused_proofs:Object.fromEntries(['docs/proofs/workshop-delivery-link-20261102.json','docs/proofs/workshop-stock-20261102.json','docs/proofs/stock-read-load-20261102.json','docs/proofs/stock-receipt-link-20261102.json'].map(p=>[p,hash(p)])),
|
|
preservation:{new_qa_schemas_and_actors_only:true,regression_not_reset:true,six_protected_records_untouched:true,blocked_cache_untouched:true,demos_untouched:true,previous_association_proofs_unchanged:true,real_rights_or_data_changed:false,indices_in_qa_fixture_only:true,purchasing_activation:false,publication:false,checkpoint:false},
|
|
limits:['One origin may not span multiple deliveries.','Consumed-material compensation and amendment/release of confirmed allocations are not implemented.','Returns accept quantity only: no lots, reservations, quality/quarantine or spare parts.','Native Purchasing return command not integrated; local artifact alone is not runtime integration.','Operational installer and one installed procurement-to-workshop composition pending.','No write-load benchmark or deployment-capacity evidence; no browser interaction or visual review.'],visual_review_pending:true,deployment_capacity_validated:false};
|
|
fs.writeFileSync('docs/proofs/workshop-material-cycle-20261102.json',JSON.stringify(report,null,2)+'\n');console.log(JSON.stringify({totals:report.totals,postcheck:report.qa_postcheck,return_manifest:report.package.manifest_sha256},null,2));
|