<?php
declare(strict_types=1);require __DIR__.'/bootstrap.php';
$check($own()===$fixture['after'],'Independent final42 exact / retained13');
$last=json_decode(file_get_contents($runtime.'/final-FINAL-original.json'),true);$check($last['original']===$fixture['after']&&$last['enum_before']===$last['enum_after'],'Final HTTP full42/179 unchanged');
$source=json_decode(file_get_contents(__DIR__.'/source-final-sha.json'),true)['files'];foreach($source as $file=>$sha)$check(hash_file('sha256',$root.'/'.$file)===$sha,'Every final6168 source pin '.$file);
$states=[];foreach(['worker-state.json','worker-FINAL-state.json'] as $name){$s=json_decode(file_get_contents($runtime.'/'.$name),true);$states[$name]=['pid'=>$s['pid'],'absent'=>!posix_kill($s['pid'],0)];$check($states[$name]['absent'],'Exact own worker absent before cleanup');}
$imgResult=null;
if($dm){
 $baseline=json_decode(file_get_contents(__DIR__.'/img-preflight-C.json'),true);$cols=$read('SELECT COLUMN_NAME,DATA_TYPE,DATA_LENGTH,CHAR_LENGTH,CHAR_USED,DATA_PRECISION,DATA_SCALE,NULLABLE,DATA_DEFAULT FROM USER_TAB_COLUMNS WHERE TABLE_NAME=? ORDER BY COLUMN_ID',['YOSHOP_STAFF']);
 $canonical=static function($rows){foreach($rows as &$row)ksort($row);unset($row);return $rows;};$check(count($cols)===21&&$canonical(array_slice($cols,0,20))===$canonical($baseline['metadata']),'Original20 exact / IMG sole21st');$img=$cols[20];$check($img['column_name']==='IMG'&&(int)$img['char_length']===256&&(int)$img['data_length']===1024&&$img['char_used']==='C'&&$img['nullable']==='N'&&trim($img['data_default'])==="''",'Fresh IMG precise contract');
 $ids=[$fixture['refs']['@staff_store'],$fixture['refs']['@staff_terminal']];foreach($ids as $id)$check(is_int($id)&&$id>0,'Own generated Staff key only');
 $sql=str_replace(' ORDER BY ID',' WHERE ID NOT IN (?,?) ORDER BY ID',$baseline['original_projection']['sql']);$s=$db->prepare($sql);$s->bindValue(1,(string)$ids[0],PDO::PARAM_STR);$s->bindValue(2,(string)$ids[1],PDO::PARAM_STR);$s->execute();$h=hash_init('sha256');$n=0;while($row=$s->fetch(PDO::FETCH_NUM)){foreach($row as &$v)if(is_resource($v))$v=stream_get_contents($v);unset($v);hash_update($h,serialize($row)."\n");$n++;}$hash=hash_final($h);$check($n===1775&&$hash===$baseline['original_projection']['sha256'],'All1775 natural/old rows full20 unchanged excluding exact2 own keys only');
 $empty=$read("SELECT COUNT(*) n FROM AIZHCT_APP.YOSHOP_STAFF WHERE ID NOT IN (?,?) AND (IMG IS NULL OR IMG<>'')",$ids);$check((int)$empty[0]['n']===0,'Only new own2 IMG nonempty');
 $objects=['indexes'=>$read('SELECT INDEX_NAME,INDEX_TYPE,UNIQUENESS,STATUS FROM USER_INDEXES WHERE TABLE_NAME=? ORDER BY INDEX_NAME',['YOSHOP_STAFF']),'index_columns'=>$read('SELECT INDEX_NAME,COLUMN_NAME,COLUMN_POSITION FROM USER_IND_COLUMNS WHERE TABLE_NAME=? ORDER BY INDEX_NAME,COLUMN_POSITION',['YOSHOP_STAFF']),'constraints'=>$read('SELECT CONSTRAINT_NAME,CONSTRAINT_TYPE,STATUS,SEARCH_CONDITION,R_CONSTRAINT_NAME FROM USER_CONSTRAINTS WHERE TABLE_NAME=? ORDER BY CONSTRAINT_NAME',['YOSHOP_STAFF']),'constraint_columns'=>$read('SELECT CONSTRAINT_NAME,COLUMN_NAME,POSITION FROM USER_CONS_COLUMNS WHERE TABLE_NAME=? ORDER BY CONSTRAINT_NAME,POSITION',['YOSHOP_STAFF']),'triggers'=>$read('SELECT * FROM USER_TRIGGERS WHERE TABLE_NAME=? ORDER BY TRIGGER_NAME',['YOSHOP_STAFF'])];foreach($objects as $name=>$value)$check($canonical($value)===$canonical($baseline['objects'][$name]),'Every original object exact '.$name);
 $comment=$read('SELECT COMMENTS FROM USER_COL_COMMENTS WHERE TABLE_NAME=? AND COLUMN_NAME=?',['YOSHOP_STAFF','IMG']);$check($comment[0]['comments']==='课程图片(OSS地址)','Final IMG source comment');$imgResult=['original1775_full20_sha256'=>$hash,'only_exact_generated2_excluded'=>true,'original20_metadata_objects_unchanged'=>true,'original_IMG_all_empty'=>true,'new_own2_IMG_marker_only'=>true,'CHAR256_bytes1024_NN_default_empty'=>true,'comment_exact'=>true];
}
$cacheFiles=0;if(is_dir($runtime.'/cache')){$it=new RecursiveIteratorIterator(new RecursiveDirectoryIterator($runtime.'/cache',FilesystemIterator::SKIP_DOTS));foreach($it as $f)if($f->isFile())$cacheFiles++;}$check($cacheFiles===0,'All private Auth/cache files absent');
$remove=static function($dir)use(&$remove){if(is_link($dir)||is_file($dir)){if(!unlink($dir))throw new RuntimeException('Own file cleanup failed');return;}if(!is_dir($dir))return;foreach(new DirectoryIterator($dir) as $f)if(!$f->isDot())$remove($f->getPathname());if(!rmdir($dir))throw new RuntimeException('Own directory cleanup failed');};
$removed=[];foreach([$root,$runtime.'/cache',$runtime.'/runtime'] as $dir){$check(strpos($dir,__DIR__.'/')===0&&$dir!==__DIR__&&$dir!==$runtime,'Exact own removable subtree only');$remove($dir);$check(!file_exists($dir),'Own temporary source/cache/runtime absent');$removed[]=$dir;}
$out=['lane'=>$lane,'final42_full_rows_exact'=>true,'retained13_full_rows_exact'=>true,'final179_enum_unchanged'=>true,'all6168_final_source_pins_verified'=>true,'own_original_final_workers'=>$states,'all_Auth_cache_files_absent'=>true,'removed_owned_paths'=>$removed,'IMG_final'=>$imgResult,'HTTP'=>0,'DML'=>0,'DDL'=>0];$persist('resource-cleanup.json',$out);file_put_contents(__DIR__.'/resource-cleanup-'.$lane.'.json',json_encode($out,JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES));echo json_encode($out),"\n";
