<?php
require __DIR__.'/runner.php';
$plan=json_decode(file_get_contents(__DIR__.'/../plan.json'),true);
$checks=0;function negative($fn,$name){global $checks;$bad=false;try{$fn();}catch(Throwable $e){$bad=true;}pf2_need($bad,'Reject '.$name);$checks++;}
pf2_gate($plan);$checks++;
$bad=$plan;$bad['steps'][0]['SQL']='DELETE FROM ZHCT_APP.YDY_PREPAY_ORDER';negative(static function()use($bad){pf2_gate($bad);},'unknownSQL');
$bad=$plan;$bad['steps'][2]['PDO_types']=[1];negative(static function()use($bad){pf2_gate($bad);},'wrongtypedbind');
$baseline=pf2_baseline('/tmp/cdx-prepay-formal-2ddl-root-package-20261011/baseline.json',$plan);$pre=$baseline['records'];pf2_phase($pre,$baseline,$plan,'pre_2ddl_fresh_stable');$checks++;
$reordered=$pre;foreach($reordered['indexes']['rows']as &$r)$r=array_reverse($r,true);unset($r);pf2_phase($reordered,$baseline,$plan,'pre_2ddl_fresh_stable');$checks++;
$after=$pre;$after['columns']['rows']=pf2_expected_columns($pre['columns']['rows'],true);$after['table_ddl']['rows'][0]['ddl']=pf2_expected_ddl($pre['table_ddl']['rows'][0]['ddl'],true);
foreach(['rows_before','rows_after']as $label)foreach($after[$label]['rows']as &$r)foreach($plan['baseline']['date_map'][$r['id_exact']]as $c=>$mapping){$r[strtolower($c)]=$mapping['source_fsp0'];$r['f_'.strtolower($c)]=$mapping['source_fsp0'].'.000000';}unset($r);
pf2_phase($after,$baseline,$plan,'after_alter_stable');$checks++;
$final=$after;$final['triggers']['rows']=[['trigger_name'=>$plan['trigger'],'table_name'=>'YDY_PREPAY_ORDER','table_owner'=>'ZHCT_APP','status'=>'Y','triggering_type'=>'BEFORE ROW','triggering_event'=>'UPDATE','trigger_body'=>$plan['steps'][35]['SQL']]];$final['new_trigger_collision']['rows']=$final['triggers']['rows'];$final['objects']['rows']=[['object_name'=>$plan['trigger'],'object_type'=>'TRIGGER','status'=>'VALID'],['object_name'=>'YDY_PREPAY_ORDER','object_type'=>'TABLE','status'=>'VALID']];$final['dependencies']['rows']=$baseline['expected_owned_dependencies'];
pf2_phase($final,$baseline,$plan,'after_trigger_stable');pf2_trigger($plan['steps'][35]['SQL'],$plan['steps'][35]['SQL']);$checks+=2;
$bad=$after;$bad['rows_after']['rows'][1]['price']=99;negative(static function()use($bad,$baseline,$plan){pf2_phase($bad,$baseline,$plan,'after_alter_stable');},'other22 changed');
$bad=$after;$bad['rows_after']['rows'][0]['raw_request_a'].='x';negative(static function()use($bad,$baseline,$plan){pf2_phase($bad,$baseline,$plan,'after_alter_stable');},'fullLOB byte changed');
$bad=$after;$bad['columns']['rows'][16]['char_length']=65535;negative(static function()use($bad,$baseline,$plan){pf2_phase($bad,$baseline,$plan,'after_alter_stable');},'TEXT misrouted as VARCHAR');
$bad=$after;$bad['rows_after']['rows'][1]['create_time']='2026-10-11 08:44:44';negative(static function()use($bad,$baseline,$plan){pf2_phase($bad,$baseline,$plan,'after_alter_stable');},'wrong old date rounding');
$bad=$final;$bad['objects']['rows'][]=['object_name'=>'PK_UNKNOWN','object_type'=>'CONSTRAINT','status'=>'VALID'];negative(static function()use($bad,$baseline,$plan){pf2_phase($bad,$baseline,$plan,'after_trigger_stable');},'USER_OBJECTS WHERE cannot return PK');
$bad=$final;$bad['indexes']['rows'][0]['status']='INVALID';negative(static function()use($bad,$baseline,$plan){pf2_phase($bad,$baseline,$plan,'after_trigger_stable');},'index validity drift');
$bad=$final;$bad['triggers']['rows'][0]['trigger_body']=str_replace('V_POS := V_POS + 256','V_POS := V_POS + 255',$plan['steps'][35]['SQL']);$bad['new_trigger_collision']['rows']=$bad['triggers']['rows'];negative(static function()use($bad,$baseline,$plan){pf2_phase($bad,$baseline,$plan,'after_trigger_stable');},'complete trigger chunk body drift');
negative(static function()use($plan){pf2_execute($plan,[]);},'worker cannot execute without Root exact release');
echo pf2_json(['status'=>'PURE_ROOT_RUNNER_TEST_GREEN','checks'=>$checks,'DB_connections'=>0,'SQL'=>0])."\n";
