<?php
declare(strict_types=1);require __DIR__.'/db.php';$check(realpath(__DIR__)==='/tmp/cdx-ai-market-sign-20261010'&&realpath($runtime)===__DIR__.'/private','Exact task cleanup root');$state=json_decode(file_get_contents($runtime.'/state.json'),true);$check(!is_file('/proc/'.$state['pid'].'/cmdline')||strpos(file_get_contents('/proc/'.$state['pid'].'/cmdline'),__DIR__.'/router.php')===false,'Own worker already stopped');$s=@fsockopen('127.0.0.1',$state['port'],$e,$m,1);$check(!$s,'Own worker port closed');
$tokens=[];foreach(['private-journal.json','private-green-journal.json','private-final-journal.json'] as $f){$j=json_decode(file_get_contents($runtime.'/'.$f),true);foreach($j['collections'] as $c)foreach($c['item'][0]['item'][0]['request']['header'] as $h)if($h['key']==='Access-Token')$tokens[$h['value']]=true;}
require $root.'/vendor/autoload.php';$app=new \think\App($root);$cache=new \think\cache\driver\File($app,['path'=>$runtime.'/cache/','prefix'=>'','expire'=>0]);$gone=true;foreach(array_keys($tokens) as $token){$cache->delete($token);$gone=$gone&&$cache->get($token)===null;}$cache->clear();$check($gone,'All collected private token entries absent');
$reports=[];if(is_dir($runtime.'/private-cli-report')){$it=new RecursiveIteratorIterator(new RecursiveDirectoryIterator($runtime.'/private-cli-report',FilesystemIterator::SKIP_DOTS));foreach($it as $f)if($f->isFile()&&$f->getExtension()==='json'){$v=json_decode(file_get_contents($f->getPathname()),true);if(!isset($v['run']['stats']))continue;$reports[]=['relative'=>substr($f->getPathname(),strlen($runtime.'/private-cli-report/')),'sha256'=>hash_file('sha256',$f->getPathname()),'stats'=>$v['run']['stats'],'failure_messages'=>array_map(static function($x){return $x['error']['message']??'unknown';},$v['run']['failures']??[])];}}$check(count($reports)===($lane==='B'?40:74),'All native reports including initial tool refusals accounted');file_put_contents(__DIR__.'/native-report-index-'.$lane.'.json',json_encode($reports,JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES));
$evidence=$runtime.'/evidence';if(!is_dir($evidence))mkdir($evidence,0700);$retained=[];foreach(['private-wire.jsonl','private-sql.jsonl','queries.jsonl','external-leaves.jsonl','private-report.json','private-green-report.json','private-final-report.json','private-harness-red-report.json','fileinfo-build.log','fileinfo-build-2.log'] as $f){$src=$runtime.'/'.$f;if(!is_file($src))continue;if(strpos($f,'report.json')!==false){$v=json_decode(file_get_contents($src),true);$check(!array_key_exists('collections',$v),'No token-bearing collections in terminal report');}copy($src,$evidence.'/'.$f);chmod($evidence.'/'.$f,0600);$retained[]=['name'=>$f,'path'=>$evidence.'/'.$f,'sha256'=>hash_file('sha256',$evidence.'/'.$f)];}
if($lane==='C'){$src=$runtime.'/fileinfo-build/modules/fileinfo.so';$check(hash_file('sha256',$src)==='c4576d36f16c8355c34021e8e6891cdb522a4254ade92eba6b864de5a861ef79','Retained private module identity');copy($src,$evidence.'/fileinfo.so');chmod($evidence.'/fileinfo.so',0600);$retained[]=['name'=>'fileinfo.so','path'=>$evidence.'/fileinfo.so','sha256'=>hash_file('sha256',$evidence.'/fileinfo.so')];}
$remove=static function($path)use(&$remove){if(is_link($path)||is_file($path)){unlink($path);return;}if(!is_dir($path))return;foreach(new DirectoryIterator($path) as $item)if(!$item->isDot())$remove($item->getPathname());rmdir($path);};
$privateFiles=[];$it=new RecursiveIteratorIterator(new RecursiveDirectoryIterator($root.'/public/uploads',FilesystemIterator::SKIP_DOTS));foreach($it as $f)if($f->isFile()){$privateFiles[]=['relative'=>substr($f->getPathname(),strlen($root.'/public/uploads/')),'sha256'=>hash_file('sha256',$f->getPathname())];}$check(count($privateFiles)===($lane==='B'?8:10),'Exact eight uploads plus C two known failed temp files');$temps=array_values(array_filter(array_column($privateFiles,'relative'),static function($p){return strpos($p,'temp/')===0;}));sort($temps);$check($temps===($lane==='B'?[]:['temp/1_1.png','temp/2_3.png']),'Only exact retained failed own temp paths');foreach($privateFiles as $f)$check($f['sha256']===hash('sha256',base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=')),'Every removed own PNG byte identity');
foreach(new DirectoryIterator($runtime) as $item)if(!$item->isDot()&&$item->getFilename()!=='evidence')$remove($item->getPathname());$remove($root);$check(!file_exists($root)&&count(array_diff(scandir($runtime),['.','..','evidence']))===0,'Only credential-free terminal evidence remains');
$out=['lane'=>$lane,'worker_pid'=>$state['pid'],'worker_stopped'=>true,'port_closed'=>true,'token_entries_verified_absent'=>count($tokens),'cache_files'=>0,'credential_bearing_CLI_reports_removed'=>count($reports),'copied_source_and_config_symlinks_removed'=>true,'private_local_PNG_files_removed'=>$privateFiles,'credential_free_terminal_evidence'=>$retained,'retained_DB_records'=>'marker-owned activities/addresses/upload metadata/storage configs retained; no natural-row cleanup','original_service_untouched'=>true,'SSH_master_owned_by_root_preserved'=>true];file_put_contents(__DIR__.'/resource-cleanup-'.$lane.'.json',json_encode($out,JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES));echo json_encode(['lane'=>$lane,'worker_stopped'=>true,'port_closed'=>true,'token_entries_absent'=>count($tokens),'cache_files'=>0,'CLI_reports_removed'=>count($reports),'private_source_removed'=>true,'terminal_evidence_retained'=>count($retained)]),"\n";
