<?php
declare(strict_types=1);
require __DIR__.'/common.php';
$path=parse_url($_SERVER['REQUEST_URI']??'',PHP_URL_PATH);$allow=['/__poc_boundary'];
foreach(['store','terminal'] as $m){foreach(['Role','Menu'] as $c){$allow[]='/'.$m.'/store.'.$c.'/list';}}
if(($_SERVER['REQUEST_METHOD']??'')!=='GET'||!in_array($path,$allow,true)){http_response_code(403);echo '{"role_menu_read_allowlist":false}';return;}
$root=getenv('ROLE_MENU_APP_ROOT');$runtime=getenv('PILOT_RUNTIME');$_SERVER['SCRIPT_FILENAME']=$root.'/public/index.php';$_SERVER['SCRIPT_NAME']='/index.php';$_SERVER['PHP_SELF']='/index.php';
try{
    $app=cpBootstrap($root,$runtime);
    foreach(['store','terminal'] as $m){foreach(['controller','model'] as $layer){foreach(['Role','Menu'] as $c){$class='app\\'.$m.'\\'.$layer.'\\store\\'.$c;$file=(new ReflectionClass($class))->getFileName();if(realpath($file)!==realpath($root.'/app/'.$m.'/'.$layer.'/store/'.$c.'.php')){throw new RuntimeException('Actual source path drift');}}}}
    if($path==='/__poc_boundary'){echo json_encode(['private_root'=>realpath(root_path())===realpath($root),'file_cache'=>$app->config->get('cache.default')==='file','external_stubs'=>class_exists(\app\common\Serve::class,false),'actual_reflection_private'=>true,'role_menu_read_allowlist'=>true]);return;}
    $map=json_decode(file_get_contents($runtime.'/fixture_map.json'),true);if(!hash_equals($map['token'],$_SERVER['HTTP_ACCESS_TOKEN']??'')||(string)($_GET['storeId']??'')!==(string)$map['tenant']){throw new RuntimeException('Private cache identity guard');}
    $scenario=$_SERVER['HTTP_X_PILOT_SCENARIO']??'';if(!preg_match('/^PILOT_RM_[A-Z0-9_]{1,50}$/D',$scenario)){throw new RuntimeException('Scenario guard');}
    if(array_diff(array_keys($_GET),['storeId','search'])){throw new RuntimeException('Frozen read params guard');}
    require __DIR__.'/SqlCoverageRecorder.php';$recorder=new SqlCoverageRecorder($runtime.'/queries.jsonl',realpath($root),$scenario);
    $app->db->listen(static function($sql,$time=null)use($recorder){if(strpos($sql,'CONNECT:')!==0){$recorder->observe($sql,$time);if(preg_match('/^\s*(INSERT|UPDATE|DELETE|MERGE|REPLACE|CREATE|ALTER|DROP|TRUNCATE)\b/i',$sql)){throw new RuntimeException('Unexpected mutation in reviewed read path');}}});
    register_shutdown_function([$recorder,'finish']);$http=$app->http;$response=$http->run();$response->send();$http->end($response);
}catch(Throwable $e){http_response_code(500);echo json_encode(['private_error'=>get_class($e),'file'=>basename($e->getFile()),'line'=>$e->getLine()]);file_put_contents($runtime.'/errors-private.jsonl',json_encode(['class'=>get_class($e),'file'=>basename($e->getFile()),'line'=>$e->getLine(),'message_sha256'=>hash('sha256',$e->getMessage())])."\n",FILE_APPEND|LOCK_EX);}
