make(Kernel::class)->bootstrap(); $root = dirname(__DIR__); $host = realpath($root.'/../sgf-tempo'); $config = DB::connection('pgsql')->getConfig(); if ($config['host'] !== '127.0.0.1') { throw new RuntimeException('Local isolated cluster required.'); } config(['database.connections.fixed_admin' => [...$config, 'url' => null, 'database' => 'postgres']]); $admin = DB::connection('fixed_admin'); $suffix = bin2hex(random_bytes(6)); $owner = 'fix_owner_'.$suffix; $runtime = 'fix_app_'.$suffix; $database = 'sgf_reproduction_'.$suffix; $ownerPassword = bin2hex(random_bytes(32)); $runtimePassword = bin2hex(random_bytes(32)); $roles = []; $created = false; $restoreCreated = false; $restoreDatabase = 'sgf_reproduction_restore_'.$suffix; $exit = 1; $work = sys_get_temp_dir().'/sgf-corrected-'.$suffix; mkdir($work, 0700); $pointer = file_get_contents($host.'/packages/purchasing/current.json'); try { $sourceSettings = Dotenv::parse(file_get_contents($host.'/.env')); $sourceEnvironment = array_intersect_key($sourceSettings, array_flip(['DB_CONNECTION', 'DB_HOST', 'DB_PORT', 'DB_DATABASE', 'DB_USERNAME', 'DB_PASSWORD', 'APP_ENV'])); $sourceEnvironment += ['APP_BASE_PATH' => $host, 'DB_URL' => $sourceSettings['DB_URL'] ?? '', 'APP_CONFIG_CACHE' => $host.'/bootstrap/cache/config.php']; $export = new Process(['powershell.exe', '-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', $host.'/scripts/sgf.ps1', 'php', $root.'/tests/Support/sgf-corrected-export.php'], $host, [...$sourceEnvironment, 'FIX_SOURCE_HOST' => $host, 'FIX_SCHEMA_FILE' => $work.'/source-schema.dump'], null, 90); $export->mustRun(); $inventory = json_decode($export->getOutput(), true, 64, JSON_THROW_ON_ERROR); if ($inventory['database'] !== $sourceSettings['DB_DATABASE']) { throw new RuntimeException('Wrong reproduction source.'); } file_put_contents($work.'/baseline.json', json_encode($inventory, JSON_THROW_ON_ERROR)); $prepare = new Process([PHP_BINARY, $root.'/scripts/prepare-sgf-operational.php', $host], $root); $prepare->mustRun(); $artifact = json_decode($prepare->getOutput(), true, 16, JSON_THROW_ON_ERROR); require $root.'/tests/Support/sgf-update-fixture.php'; $manifest = json_decode(file_get_contents($artifact['directory'].'/manifest.json'), true, 32, JSON_THROW_ON_ERROR); $clone = updateFixture($host, $manifest, true); foreach ([$owner => $ownerPassword, $runtime => $runtimePassword] as $role => $password) { $admin->statement('CREATE ROLE "'.$role.'" LOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOBYPASSRLS PASSWORD '.$admin->getPdo()->quote($password)); $roles[] = $role; } $admin->statement('CREATE DATABASE "'.$database.'" OWNER "'.$owner.'"'); $created = true; $env = ['APP_ENV' => 'production', 'APP_DEBUG' => 'false', 'APP_BASE_PATH' => $clone, 'APP_KEY' => 'base64:'.base64_encode(random_bytes(32)), 'DB_CONNECTION' => 'pgsql', 'DB_URL' => '', 'DB_HOST' => '127.0.0.1', 'DB_PORT' => (string) $config['port'], 'DB_DATABASE' => $database, 'DB_USERNAME' => $owner, 'DB_PASSWORD' => $ownerPassword, 'SESSION_DRIVER' => 'file', 'SESSION_FILES' => $clone.'/storage/framework/sessions', 'SESSION_COOKIE' => 'corrected_'.$suffix, 'CACHE_STORE' => 'array', 'QUEUE_CONNECTION' => 'sync', 'FIX_SOURCE_HOST' => $host, 'FIX_CLONE' => $clone, 'FIX_BUNDLE' => $artifact['directory'], 'FIX_ROOT' => $root, 'FIX_WORK' => $work, 'FIX_RUNTIME' => $runtime, 'FIX_RUNTIME_PASSWORD' => $runtimePassword]; $restore = new Process(['C:/Program Files/PostgreSQL/17/bin/pg_restore.exe', '--no-owner', '--no-privileges', '--exit-on-error', '--dbname='.$database, $work.'/source-schema.dump'], null, ['PGHOST' => '127.0.0.1', 'PGPORT' => (string) $config['port'], 'PGUSER' => $owner, 'PGPASSWORD' => $ownerPassword], null, 60); $restore->mustRun(); $proofProcess = new Process(['powershell.exe', '-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', $host.'/scripts/sgf.ps1', 'php', $root.'/tests/Support/sgf-corrected-proof.php'], $host, $env, null, 180); $proofProcess->mustRun(); try { $proof = json_decode($proofProcess->getOutput(), true, 64, JSON_THROW_ON_ERROR); } catch (JsonException) { file_put_contents($work.'/failure.txt', $proofProcess->getOutput().$proofProcess->getErrorOutput()); throw new RuntimeException('Private diagnostic '.$work.'/failure.txt'); } file_put_contents($work.'/expected.json', json_encode($proof['data_fingerprints'], JSON_THROW_ON_ERROR)); $admin->statement('CREATE DATABASE "'.$restoreDatabase.'" OWNER "'.$owner.'"'); $restoreCreated = true; $restoreData = new Process(['C:/Program Files/PostgreSQL/17/bin/pg_restore.exe', '--no-owner', '--no-privileges', '--exit-on-error', '--dbname='.$restoreDatabase, $work.'/installed.dump'], null, ['PGHOST' => '127.0.0.1', 'PGPORT' => (string) $config['port'], 'PGUSER' => $owner, 'PGPASSWORD' => $ownerPassword], null, 90); $restoreData->mustRun(); $readRestore = new Process(['powershell.exe', '-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', $host.'/scripts/sgf.ps1', 'php', $root.'/tests/Support/sgf-corrected-restored.php'], $host, [...$env, 'DB_DATABASE' => $restoreDatabase], null, 60); $readRestore->mustRun(); $proof['data_recovery'] = json_decode($readRestore->getOutput(), true, 32, JSON_THROW_ON_ERROR); $after = new Process(['powershell.exe', '-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', $host.'/scripts/sgf.ps1', 'php', $root.'/tests/Support/sgf-corrected-export.php'], $host, [...$sourceEnvironment, 'FIX_SOURCE_HOST' => $host, 'FIX_CHECK_ONLY' => '1'], null, 60); $after->mustRun(); $afterState = json_decode($after->getOutput(), true, 64, JSON_THROW_ON_ERROR); if ($afterState['source_security_fingerprints'] !== $inventory['source_security_fingerprints'] || $afterState['tables'] !== $inventory['tables']) { throw new RuntimeException('Destination changed during isolated proof; reconcile.'); } $proof['destination_security_and_schema_preserved'] = true; if (! $proof['passed'] || file_get_contents($host.'/packages/purchasing/current.json') !== $pointer) { throw new RuntimeException('Proof or destination preservation failed.'); } $proof += ['artifact' => $artifact, 'source_schema_tables' => count($inventory['tables']), 'source_rows_exported' => 0, 'source_schema_sha256' => $inventory['schema_sha256'], 'runtime_and_migrator_separate' => true, 'destination_version' => '0.1.1', 'destination_changed' => false, 'prior_proofs_reused' => true, 'checked_at' => gmdate('c')]; $exit = 0; } catch (Throwable $error) { fwrite(STDERR, $error->getMessage()."\n"); } finally { if ($restoreCreated) { $admin->select('select pg_terminate_backend(pid) from pg_stat_activity where datname=? and pid<>pg_backend_pid()', [$restoreDatabase]); $admin->statement('DROP DATABASE "'.$restoreDatabase.'"'); } if ($created) { $admin->select('select pg_terminate_backend(pid) from pg_stat_activity where datname=? and pid<>pg_backend_pid()', [$database]); $admin->statement('DROP DATABASE "'.$database.'"'); }foreach (array_reverse($roles) as $role) { $admin->statement('DROP ROLE "'.$role.'"'); } } if ($exit === 0) { $proof['test_database_and_roles_removed'] = true; file_put_contents($root.'/docs/proofs/sgf-corrected-delivery.json', json_encode($proof, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR)); echo json_encode($proof,JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR)."\n"; }exit($exit);