<?php
declare(strict_types=1);require __DIR__.'/common.php';$check(is_file($runtime.'/end-inspection.json'),'End inspection must exist');$expectedBase=$lane==='B'?'/workspace/zhct/zhctprompt/work_ai_api/2026-09-30-dm8-interface-acceptance/parallel-ai-investigate-write3-20261011':'/tmp/cdx-ai-investigate-write3-20261011';$check(dirname(__DIR__)===$expectedBase,'Exact own runtime root');$state=json_decode(file_get_contents($runtime.'/worker-state.json'),true);$port=$lane==='B'?18911:18912;$check($state['port']===$port,'Exact own worker port');$cmd=@file_get_contents('/proc/'.$state['pid'].'/cmdline');$check(!$cmd||strpos($cmd,__DIR__.'/router.php')===false,'Own new worker already stopped');$old=json_decode(file_get_contents($prior.'/worker-state.json'),true);$oldCmd=@file_get_contents('/proc/'.$old['pid'].'/cmdline');$check(!$oldCmd||strpos($oldCmd,$expectedBase.'/router.php')===false,'Own previous worker already stopped');$s=@fsockopen('127.0.0.1',$port,$e,$m,1);if($s)fclose($s);$check(!$s,'Exact own port closed');$check($protected()===json_decode(file_get_contents($runtime.'/preflight.json'),true)['protected'],'Final protected before resource cleanup');$own=$small();$final=json_decode(file_get_contents($runtime.'/end-inspection.json'),true);$check($own===$final['own'],'All retained marked business rows exact before cleanup');$app=invApp($root,$runtime,'AUTH_CLEANUP');InvGate::$case=['kind'=>'read'];$tokenCounts=[];foreach([$prior,$runtime] as $dir){$tokens=json_decode(file_get_contents($dir.'/tokens.json'),true);$oldPath=$app->config->get('cache.stores.file.path');$app->config->set(['default'=>'file','stores'=>['file'=>['type'=>'File','path'=>$dir.'/cache/','prefix'=>'','expire'=>0]]],'cache');$cache=new \think\Cache($app);foreach($tokens as $token){$cache->delete($token);$check($cache->get($token)===null,'Own cache token revoked');}$tokenCounts[]=['location'=>$dir===$prior?'prior':'finish','revoked'=>count($tokens)];$check(unlink($dir.'/tokens.json'),'Own token file erased');}
$snapshot=json_decode(file_get_contents(__DIR__.'/source-final-sha.json'),true)['files'];$check(count($snapshot)===6168,'Final whole source pin count');foreach($snapshot as $name=>$sha)$check(hash_file('sha256',$root.'/'.$name)===$sha,'Exact source deletion lease '.$name);
$allowed=[$root,$prior.'/cache',$prior.'/runtime',$runtime.'/cache',$runtime.'/runtime'];$removed=[];$erase=static function($path)use($allowed,&$removed,$check){$check(in_array($path,$allowed,true)&&strpos($path,'/parallel-ai-investigate-write3-20261011/')!==false||in_array($path,$allowed,true)&&strpos($path,'/tmp/cdx-ai-investigate-write3-20261011/')===0,'Exact own deletion path');if(!is_dir($path))return;$check(!is_link($path)&&realpath($path)===$path,'No root symlink');$files=0;$dirs=0;$it=new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path,FilesystemIterator::SKIP_DOTS),RecursiveIteratorIterator::CHILD_FIRST);$entries=[];foreach($it as $file){$check(!$file->isLink(),'No contained symlink');$entries[]=$file->getPathname();}foreach($entries as $entry){if(is_dir($entry)){$check(rmdir($entry),'Remove own exact directory');$dirs++;}else {$check(unlink($entry),'Remove own exact file');$files++;}}$check(rmdir($path),'Remove own root');$removed[]=['path'=>str_replace(dirname(__DIR__),'OWN_ROOT',$path),'files'=>$files,'directories'=>$dirs+1];};foreach($allowed as $path)$erase($path);
$persist('cleanup.json',['lane'=>$lane,'own_current_worker'=>$state,'own_original_worker'=>$old,'own_workers_stopped'=>true,'own_port_closed'=>true,'token_cache_revocations'=>$tokenCounts,'token_files_erased'=>true,'source6168_pin_before_delete'=>true,'removed_owned_resources'=>$removed,'business_rows_retained'=>['masters'=>count($own['nutrition_meals']),'answers'=>count($own['nutrition_lack'])],'protected_data_exact'=>true,'HTTP'=>0,'business_DML'=>0,'DDL'=>0,'unrelated_original_parent_processes_untouched'=>true]);echo json_encode(['lane'=>$lane,'own_worker_stopped'=>true,'port_closed'=>true,'tokens_revoked'=>4,'source_copy_erased'=>true,'marked_business_rows_retained'=>count($own['nutrition_meals'])+count($own['nutrition_lack']),'HTTP'=>0,'business_DML'=>0,'DDL'=>0]),"\n";
