$host,'native'=>$native]as$name=>$db)foreach(array_unique(array_merge(array_keys($baseline[$name]),$name==='host'?['wo_orders','wo_entries','wo_decisions','wo_equipment','wo_commands','wo_events']:[]))as$table)$before[$name][$table]=$db->table($table)->orderBy('id')->get()->toJson();$binding=hash_file('sha256',$s['root'].'/binding.json'); $build=$run['root'].'/private/single-overview-build-20261110';$manifest=json_decode(file_get_contents($build.'/manifest.json'),true);if(!isset($manifest['resources/js/app.jsx']))throw new LogicException('Build manifest missing'); $files=['resources/js/context-transition.js','routes/web.php','app/Modules/Workshop/WorkshopOrderRead.php','app/Modules/Workshop/Http/WorkshopOrderReadController.php','resources/js/WorkshopMenuWorkspace.jsx','resources/js/WorkshopOrderList.jsx','resources/js/WorkspaceHome.jsx','resources/js/workspace-overview.js','resources/js/ModuleNavigation.jsx','resources/js/app.jsx','resources/js/StockMenuWorkspace.jsx','resources/css/tempo-theme.css','app/Shared/Installation/PresentationEntry.php','resources/views/sgf-presentation-entry.blade.php'];foreach($files as$file)if(str_ends_with($file,'.php'))(new Symfony\Component\Process\Process([PHP_BINARY,'-l',$repo.'/'.$file]))->mustRun();$hashes=[];$copy=function($src,$file)use($s,$work,&$hashes){$dest=$s['app'].'/'.$file;$backup=$work.'/before/'.$file;if(is_file($dest)){if(!is_dir(dirname($backup)))mkdir(dirname($backup),0700,true);copy($dest,$backup);}if(!is_dir(dirname($dest)))mkdir(dirname($dest),0700,true);copy($src,$dest);$hashes[$file]=hash_file('sha256',$dest);};foreach($files as$file)$copy($repo.'/'.$file,$file); $assets=[];foreach($manifest as$entry){$assets[]=$entry['file'];foreach($entry['css']??[]as$file)$assets[]=$file;}foreach(array_unique($assets)as$file){if(!preg_match('~^assets/[a-zA-Z0-9_.-]+$~D',$file))throw new LogicException('Invalid asset path');$copy($build.'/'.$file,'public/build/'.$file);}$copy($build.'/manifest.json','public/build/manifest.json'); $checks=[];foreach(['host'=>$host,'native'=>$native]as$name=>$db)foreach($before[$name]as$table=>$json){if($db->table($table)->orderBy('id')->get()->toJson()!==$json)throw new LogicException('Original facts changed '.$table);$checks[]=$name.'.'.$table;}if(hash_file('sha256',$s['root'].'/binding.json')!==$binding)throw new LogicException('Binding changed');if($native->table('gl_journals')->count()!==27||$host->table('fr_calculations')->count()!==5)throw new LogicException('Original counts changed'); file_put_contents($work.'/overview-installation.json',json_encode(['passed'=>true,'hashes'=>$hashes,'identical_original_tables'=>$checks,'journals'=>27,'fiscal_calculations'=>5,'business_commands'=>0,'new_grants'=>0,'new_demo'=>false,'cache_cleared'=>false,'native_writes'=>0,'binding_unchanged'=>true],JSON_PRETTY_PRINT));echo json_encode(['passed'=>true,'proof'=>$work.'/overview-installation.json']).PHP_EOL;