<?php
declare(strict_types=1);
require __DIR__.'/bootstrap.php';require __DIR__.'/oracle.php';require __DIR__.'/StrictWire.php';require __DIR__.'/SqlCoverageRecorder.php';$red=json_decode(file_get_contents($runtime.'/private-report.json'),true);$green=json_decode(file_get_contents($runtime.'/private-green-report.json'),true);$v2=json_decode(file_get_contents($runtime.'/private-v2-report.json'),true);$fresh=analysisOriginalSnapshot($read,$tenant,$staff,$operator);$hash=hash('sha256',serialize($fresh));$check($hash===$red['before_sha256']&&$hash===$green['before_sha256']&&$green['after_sha256']===$hash&&$v2['original_unchanged'],'Independent fresh original rows unchanged across original/v1/v2');$check($red['errors']===[]&&$green['errors']===[]&&count($red['cases'])===7&&count($green['cases'])===7&&count($v2['cases'])===2,'All three phases actual HTTP checkpoints');
$objects=['original'=>json_decode(file_get_contents($runtime.'/private-report.json'))->cases,'candidate_v1'=>json_decode(file_get_contents($runtime.'/private-green-report.json'))->cases,'candidate_v2'=>json_decode(file_get_contents($runtime.'/private-v2-report.json'))->cases];
$typed=static function($v)use(&$typed){if(is_object($v)){$a=get_object_vars($v);ksort($a);$o=[];foreach($a as $k=>$x)$o[$k]=$typed($x);return ['type'=>'object','members'=>$o];}if(is_array($v))return ['type'=>'array','items'=>array_map($typed,$v)];return ['type'=>gettype($v),'value_sha256'=>hash('sha256',serialize($v))];};$cases=[];$mysqlUnchanged=[];$differenceCount=0;foreach(['original'=>$red,'candidate_v1'=>$green] as $phase=>$report)foreach($report['cases'] as $index=>$c){$check($c['http_status']===200&&$c['business_status']===200&&$c['consumed_original_unchanged'],'Native full original state '.$phase);$data=$objects[$phase][$index]->actual_body->data;$want=$objects[$phase][$index]->expected_data;$equal=strictWireEqual($data,$want);$check($equal===$c['complete_original_equal'],'Saved complete comparator result');if($phase==='candidate_v1')$check($equal&&$c['native_exit']===0,'V1 original projection pass');if($phase==='original')$differenceCount+=count($c['difference']);$cases[]=['phase'=>$phase,'scenario'=>$c['scenario'],'method'=>$c['method'],'path'=>$c['path'],'type'=>$c['type'],'http_status'=>$c['http_status'],'business_status'=>$c['business_status'],'native_exit'=>$c['native_exit'],'complete_original_equal'=>$equal,'actual_contract'=>$typed($data),'expected_contract'=>$typed($want),'difference'=>$c['difference'],'raw_response_sha256'=>$c['raw_sha256'],'consumed_original_unchanged'=>true];}
foreach($v2['cases'] as $index=>$c){$check($v2['native_exit']===0&&$c['http_status']===200&&$c['complete_original_equal'],'V2 vitamin necessary native regression');$cases[]=['phase'=>'candidate_v2','scenario'=>$c['scenario'],'http_status'=>$c['http_status'],'native_exit'=>$v2['native_exit'],'complete_original_equal'=>true,'actual_contract'=>$typed($objects['candidate_v2'][$index]->actual_body->data),'expected_contract'=>$typed($objects['candidate_v2'][$index]->expected_data),'raw_response_sha256'=>$c['raw_sha256']];}
if($lane==='B'){foreach($objects['original'] as $i=>$old){$new=$objects['candidate_v1'][$i];$a=clone $old->actual_body;$b=clone $new->actual_body;unset($a->trace_id,$b->trace_id);$check(strictWireEqual($a,$b),'MySQL original complete body unchanged except top trace');$mysqlUnchanged[]=['scenario'=>$old->scenario,'complete_body_unchanged_except_top_trace'=>true,'sha256'=>hash('sha256',serialize($typed($a)))];}foreach($objects['candidate_v2'] as $c){$name=str_replace('PILOT_TA_V2_','PILOT_TA_',$c->scenario);$old=null;foreach($objects['original'] as $x)if($x->scenario===$name)$old=$x;$check($old!==null&&strictWireEqual($old->actual_body->data,$c->actual_body->data),'MySQL V2 complete data unchanged');}}
$dml=0;$audit=[];$scoped=['meal','meal_infos','dishes','meal_recommend','meal_score_subtable','dietary_recommend'];foreach(file($runtime.'/private-sql.jsonl',FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES) as $line){$v=json_decode($line,true);$sql=$v['sql'];if(preg_match('/^\s*(INSERT|UPDATE|DELETE|REPLACE|MERGE|ALTER|DROP|CREATE)\b/i',$sql))$dml++;$business=[];foreach($scoped as $t)if(preg_match('/^\s*SELECT\b/i',$sql)&&preg_match('/\b(?:FROM|JOIN)\s+["`]?yoshop_'.$t.'["`]?\b/i',$sql))$business[]=$t;$tenantBound=!$business||preg_match('/store_id["`]?\s*=\s*[\x27]?'.$tenant.'\b/i',$sql)===1;$check($tenantBound,'Actual SELECT tenant predicate for scoped table');$audit[]=['scenario'=>$v['scenario'],'operation'=>SqlCoverageRecorder::fingerprint($sql)['operation'],'business_tables'=>$business,'tenant_scope_verified'=>$tenantBound,'sql_sha256'=>hash('sha256',$sql)];}$check($dml===0,'DML0');$cache->clear();$counts=[];foreach($fresh as $name=>$rows)$counts[$name]=is_array($rows)?count($rows):1;
$out=['lane'=>$lane,'natural_data_policy'=>'Each lane independently projected its own original rows; no cross-lane business-value equality assumed','cases'=>$cases,'original_type_difference_paths'=>$differenceCount,'native_stats'=>['original'=>$red['stats'],'candidate_v1'=>$green['stats'],'candidate_v2'=>$v2['stats']],'boundary'=>['original'=>$red['boundary'],'candidate_v1'=>$green['boundary'],'candidate_v2'=>$v2['boundary']],'original_snapshot_sha256'=>$hash,'original_consumption_counts'=>$counts,'original_rows_unchanged'=>true,'business_DML'=>$dml,'sql_audit'=>$audit,'MySQL_complete_body_invariance'=>$mysqlUnchanged,'metadata'=>$metadata,'limitation'=>['dietary_recommend_empty'=>$metadata['metadata']['dietary_recommend']['rows']===0,'natural_scores_empty'=>true],'tokens_cache_reclaimed'=>true];file_put_contents(__DIR__.'/evidence-'.$lane.'.json',json_encode($out,JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES|JSON_PRESERVE_ZERO_FRACTION));
$items=[];foreach($green['collections'] as $collection){$item=$collection['item'][0]['item'][0];foreach($item['request']['header'] as &$h)if($h['key']==='Access-Token')$h['value']='{{terminal_token}}';unset($h);$item['request']['url']=preg_replace('/staff_id=\d+/','staff_id={{staff_id}}',str_replace($base,'{{base_url}}',$item['request']['url']));$item['event'][0]['script']['exec'][3]="pm.test('Business status only; full original oracle requires private runner',function(){pm.expect(b.status).to.eql(200);});";$items[]=$item;}$collection=['apifoxCli'=>'2.2.8','info'=>['name'=>'设备营养分析只读路由smoke，完整原表oracle由本地runner生成且私有'],'item'=>[['name'=>'terminal Analysis六方法七分支','item'=>$items]]];file_put_contents(__DIR__.'/terminal-analysis-readonly-'.$lane.'.apifox-cli.json',json_encode($collection,JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES));echo json_encode(['lane'=>$lane,'native_HTTP'=>count($cases),'original_type_difference_paths'=>$differenceCount,'all_candidate_cases_original_equal'=>true,'business_DML'=>$dml,'original_rows_unchanged'=>true]),"\n";
