'testing', 'APP_DEBUG' => 'true', 'APP_URL' => 'http://127.0.0.1:18094', 'APP_KEY' => 'base64:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=', 'DB_CONNECTION' => 'pgsql', 'DB_HOST' => '127.0.0.1', 'DB_PORT' => '55441', 'DB_DATABASE' => $target['database'], 'DB_USERNAME' => 'postgres', 'DB_PASSWORD' => '', 'DB_URL' => '', 'SESSION_DRIVER' => 'file', 'SESSION_COOKIE' => 'origin_review_qa', 'CACHE_STORE' => 'array', 'QUEUE_CONNECTION' => 'sync'] as $key => $value) { putenv($key.'='.$value); $_ENV[$key] = $_SERVER[$key] = $value; } require $root.'/vendor/autoload.php'; $app = require $root.'/bootstrap/app.php'; $app->make(Kernel::class)->bootstrap(); $c = config('database.connections.pgsql'); if (config('database.default') !== 'pgsql' || $c['host'] !== '127.0.0.1' || (int) $c['port'] !== 55441 || $c['database'] !== $target['database'] || ! empty($c['url'])) { throw new RuntimeException('Refusing non-QA configuration.'); } $identity = DB::selectOne('SELECT current_database() AS database,inet_server_port() AS port'); if ($identity->database !== $target['database'] || (int) $identity->port !== 55441) { throw new RuntimeException('Refusing non-QA database.'); } $qa = $directory.'/qa-origin-review'; if (! is_dir($qa.'/sessions')) { mkdir($qa.'/sessions', 0700, true); } config(['session.files' => $qa.'/sessions', 'portal.managers' => ['origin-browser@example.invalid'], 'opportunity_origin.proof_path' => $qa.'/proof.json', 'suitecrm.enabled' => false, 'investmoz_ai.enabled' => false]); Vite::useHotFile($root.'/storage/framework/origin-qa-absent-hot'); if (PHP_SAPI === 'cli' && ($argv[1] ?? '') === 'seed') { $user = User::updateOrCreate(['email' => 'origin-browser@example.invalid'], ['name' => 'Origin review QA', 'password' => Hash::make('Origin-QA-2026!')]); $user->forceFill(['email_verified_at' => now()])->save(); file_put_contents($qa.'/proof.json', json_encode([...$proof, 'target' => $target, 'reversal_verified' => true, 'fixture_only' => true, 'code_hash' => app(OpportunityOriginReview::class)->fingerprint()], JSON_THROW_ON_ERROR)); echo json_encode(['target' => $target, 'qa_user' => $user->id, 'code_hash' => app(OpportunityOriginReview::class)->fingerprint(), 'active_writes' => 0]).PHP_EOL; exit; } if (PHP_SAPI === 'cli' && ($argv[1] ?? '') === 'verify') { $hashes = []; foreach (['opportunities', 'opportunity_projects', 'opportunity_clusters', 'opportunity_favourites', 'interest_requests', 'interest_submission_receipts', 'investment_messages', 'tasks', 'project_locations', 'cluster_projects'] as $table) { $qualified = '"public"."'.$table.'"'; $rows = DB::select('SELECT row_to_json(t)::text AS row_json FROM '.$qualified.' t ORDER BY row_to_json(t)::text'); $hashes[$qualified] = hash('sha256', implode("\n", array_map(fn ($row) => $row->row_json, $rows))); if ($hashes[$qualified] !== $proof['table_hashes'][$qualified]) { throw new RuntimeException('Record/interaction preservation failed: '.$table); } } $events = DB::table('audit_events')->where('source_system', 'opportunity-origin-review')->orderBy('occurred_at')->get(); $state = app(OpportunityOriginReview::class)->state(1); if ($state['classification'] !== 'undetermined' || $events->count() !== 2) { throw new RuntimeException('QA classification cycle incomplete.'); } $evidence = ['verified_at' => gmdate('c'), 'target' => $target, 'hashes' => $hashes, 'classification_restored' => $state['classification'] === 'undetermined', 'decision_events' => $events->count(), 'code_hash' => app(OpportunityOriginReview::class)->fingerprint(), 'active_writes' => 0]; file_put_contents($directory.'/opportunity-origin-reversal-evidence.json', json_encode($evidence, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR)); echo json_encode($evidence, JSON_THROW_ON_ERROR).PHP_EOL; exit; } $path = rawurldecode(parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH) ?: '/'); $asset = realpath($root.'/public'.$path); $public = realpath($root.'/public'); if ($path !== '/' && $asset && $public && str_starts_with($asset, $public.DIRECTORY_SEPARATOR) && is_file($asset)) { return false; } header('X-Investmoz-QA-Target: '.$identity->database.':'.$identity->port); $app->handleRequest(Request::capture());