begin(), 'Fresh synthetic request begins.'); $task = 'fixture-task-' . $number; $control->bindTask('qwen', 'fixture-user', $task, $run); return [$control, $task, $dir . '/' . hash('sha256', '7:11:' . $uuid) . '.json', $uuid]; }; $read = static fn (string $path): array => json_decode(file_get_contents($path), true, 512, JSON_THROW_ON_ERROR); $write = static function (string $path, array $state): void { file_put_contents($path, json_encode($state, JSON_THROW_ON_ERROR)); }; $reply = static fn (array $identity, string $status): array => ['ok' => true, 'workflow_run_id' => $identity['workflow_run_id'], 'status' => $status]; try { [$c, $task, $path, $uuid] = $make(); $c->markStop(true, $task); $c->markTerminal($task, 'stopped', 'fixture-run'); $p = $c->publicState(); $expect($p['producer_terminal_received'] && !$p['upstream_terminal_confirmed'] && $p['upstream_pending_task_count'] === 1, 'Stop acceptance / SSE receipt is not independent cleanup.'); $expect(!$c->canStartAttempt() && isset($read($path)['upstream']), 'SSE stopped retains identity and blocks successor.'); $calls = 0; $running = static function (array $id, int $ms) use (&$calls, $c, $path, $read, $expect, $reply): array { ++$calls; $expect($ms > 0 && $ms <= 1000, 'Original one-second I/O cap.'); $expect(!$c->canStartAttempt() && $read($path)['transfer_closed'], 'Own generation is closed before lookup; gate remains closed during I/O.'); $peer = new Control(7, 11, $GLOBALS['r26CurrentUuid'], dirname($path)); $nested = $peer->reconcileTerminal($id['task_id'], static function (): array { throw new \RuntimeException('Peer must not duplicate claim'); }); $expect(in_array($nested['reason'], ['verification_in_progress', 'attempts_exhausted'], true), 'Cross-worker claim survives outside unlocked I/O.'); return $reply($id, 'running'); }; $GLOBALS['r26CurrentUuid'] = $uuid; $closed = $c->closeGeneration($task, $running); $state = $read($path); $p = $c->publicState(); $expect(!$closed['confirmed'] && $closed['pending'] && $calls === 2, 'At most two original-pair lookups, never a model request.'); $expect($p['persisted_run_status'] === 'running' && $p['producer_terminal_status'] === 'stopped' && $p['lifecycle_conflict'], 'Contrary statuses both retained without override.'); $expect($p['upstream_pending_task_count'] === 1 && !$c->canStartAttempt(), 'Contradiction blocks compatibility/continuation handoff.'); $expect(count($state['run_status_observations']) === 2 && $state['verification_attempts'] === 2, 'Bounded private observation history.'); $started = $state['verification_started_at']; $c->closeGeneration($task, $running); $c->finish('error'); $c->reconcileClosedTasks($running); $expect($calls === 2 && $read($path)['verification_started_at'] === $started, 'Repeated close/final recovery never renews attempts or budget.'); $state = $read($path); $state['expires_at'] = time() - 1000; $write($path, $state); touch($path, time() - 1000); $peer = new Control(7, 11, $uuid, $dir); $expect(is_file($path) && $peer->publicState()['upstream_pending_task_count'] === 1 && !$peer->begin(), 'TTL/GC retains contradiction and original identity.'); foreach (['producer_terminal_observed_at','persisted_run_observed_at','stop_accepted_at','generation_transfer_closed_at'] as $key) $expect(is_float($p[$key]) && $p[$key] > 0, 'Distinct observation time: ' . $key); $expect(!str_contains(json_encode($p), $task) && !str_contains(json_encode($p), 'fixture-run') && !str_contains(json_encode($p), 'fixture-user'), 'Public receipts never reveal original identities.'); foreach (['stopped','succeeded','failed'] as $status) { [$c,$task,$path] = $make(); $c->markTerminal($task,$status,'fixture-run'); $calls=0; $r=$c->reconcileTerminal($task,static function () use (&$calls): array {++$calls;return [];}); $expect($r['reason']==='transport_open' && $calls===0, 'No lookup from a live transport/SSE callback.'); $r=$c->closeGeneration($task,static function(array $id,int $ms)use($reply,$status,&$calls):array{++$calls;return $reply($id,$status);}); $state=$read($path); $expect($r['confirmed'] && $calls===1 && $c->canStartAttempt(), 'Independent terminal agreement permits successor.'); $expect(!isset($state['upstream']) && count($state['completed_generations'])===1, 'Original pair and receipts archived privately after completion.'); $archive=array_values($state['completed_generations'])[0]; $expect($archive['upstream']['task_id']===$task && $archive['producer_terminal_status']===$status && $archive['persisted_run_status']===$status, 'Archive retains exact generation/pair and separate status sources.'); $c->closeGeneration($task,static function():array{throw new \RuntimeException('No repeated completed lookup');}); try {$c->bindTask('qwen','fixture-user',$task,'fixture-run');$expect(false,'Completed identity must not get a new budget');} catch(\RuntimeException $e){$expect($e->getMessage()==='UPSTREAM_TASK_IDENTITY_CONFLICT','Completed identity cannot be replayed as a fresh generation.');} $c->bindTask('qwen','fixture-user','next-'.$task,'next-run-'.$task); $expect(!$c->canStartAttempt() && count($read($path)['completed_generations'])===1, 'New generation gets own pending state and preserves prior receipts.'); } foreach (['foreign_run','foreign_task','foreign_user','foreign_profile','missing_ok','false_ok','string_ok','bad_status'] as $bad) { [$c,$task,$path]=$make(); $c->markTerminal($task,'stopped','fixture-run'); $c->closeGeneration($task,static function(array $id)use($bad,$reply):array{ $r=$reply($id,'succeeded'); if($bad==='foreign_run')$r['workflow_run_id']='foreign-run'; if($bad==='foreign_task')$r['task_id']='foreign-task'; if($bad==='foreign_user')$r['user']='foreign-user'; if($bad==='foreign_profile')$r['profile']='openai'; if($bad==='missing_ok')unset($r['ok']); if($bad==='false_ok')$r['ok']=false; if($bad==='string_ok')$r['ok']='true'; if($bad==='bad_status')$r['status']='finished'; return $r; }); $expect(!$c->publicState()['upstream_terminal_confirmed'] && isset($read($path)['upstream']), 'Malformed/foreign lookup cannot erase identity: '.$bad); $expect(!isset($read($path)['persisted_run_status']), 'Unverified alias/status is never a recorded run observation.'); } foreach (['scheduled','running','partial-succeeded','paused'] as $status) { [$c,$task,$path]=$make();$c->markTerminal($task,'stopped','fixture-run');$calls=0; $c->closeGeneration($task,static function(array $id)use($status,$reply,&$calls):array{++$calls;return $reply($id,$status);}); $p=$c->publicState(); $expect($calls===2 && $p['persisted_run_status']===$status && !$p['upstream_terminal_confirmed'] && !$c->canStartAttempt(), 'Nonterminal allowlist is observational only: '.$status); $stopCalls=0;$c->requestCancel(static function()use(&$stopCalls):bool{++$stopCalls;return true;}); $expect($stopCalls===0 && $c->publicState()['cancel_requested'], 'Producer receipt avoids redundant stop I/O without certifying cleanup.'); } [$c,$task,$path]=$make();$c->markTerminal($task,'stopped','fixture-run');$calls=0; $r=$c->closeGeneration($task,static function(array $id)use(&$calls,$reply):array{return $reply($id,++$calls===1?'running':'succeeded');}); $state=$read($path);$archive=array_values($state['completed_generations'])[0]; $expect($r['confirmed'] && $c->canStartAttempt() && $c->publicState()['lifecycle_conflict'], 'Later exact independent terminal proves ended while retaining disagreement history.'); $expect(array_column($archive['run_status_observations'],'status')===['running','succeeded'] && $archive['producer_terminal_status']==='stopped', 'Both exact run observations and original producer receipt survive archive.'); foreach(['generation','task_id','workflow_run_id','profile','user','token']as$changed){ [$c,$task,$path]=$make();$c->markTerminal($task,'stopped','fixture-run'); $r=$c->closeGeneration($task,static function(array $id)use($changed,$path,$read,$write,$reply):array{ $state=$read($path); if($changed==='generation')++$state['upstream']['generation']; elseif($changed==='token')$state['verification_claim']['token']='replacement'; else $state['upstream'][$changed]='replacement'; $write($path,$state);return $reply($id,'succeeded'); }); $expect($r['reason']==='stale_result' && !isset($read($path)['persisted_run_status']) && !$c->canStartAttempt(), 'Changed ownership/claim cannot receive an old verification result: '.$changed); } [$c,$task,$path]=$make(); $c->markTerminal('foreign-task','stopped','fixture-run'); $c->markTerminal($task,'stopped','wrong-run'); $expect(!$c->publicState()['producer_terminal_received'], 'Foreign producer receipts cannot establish status.'); $c->markTerminal($task,'stopped','fixture-run'); $c->closeGeneration($task,static function(array $id)use($reply):array{$GLOBALS['r26Clock']+=1100000000;return $reply($id,'succeeded');}); $expect(!$c->publicState()['upstream_terminal_confirmed'] && isset($read($path)['upstream']), 'Late response never confirms cleanup.'); [$c,$task,$path]=$make(); $c->markTerminal($task,'stopped','fixture-run'); $r=$c->closeGeneration($task,static function(array $id)use($path,$read,$write,$reply):array{ $state=$read($path);$state['upstream']['generation']++;$write($path,$state);return $reply($id,'succeeded'); }); $expect($r['reason']==='stale_result' && !isset($read($path)['persisted_run_status']), 'Generation race cannot apply stale same-run result.'); [$c,$task,$path]=$make(''); $c->markTerminal($task,'stopped'); $calls=0; $r=$c->closeGeneration($task,static function()use(&$calls):array{++$calls;return [];}); $expect($r['reason']==='identity_unavailable' && $calls===0 && $c->publicState()['upstream_pending_task_count']===1, 'Legacy task-only terminal remains unconfirmed without guessed run.'); [$c,$task,$path]=$make(); $legacy=$read($path);$legacy['upstream_terminal_confirmed']=true;$legacy['upstream_terminal_status']='stopped';$write($path,$legacy); $c->clearTask($task); $expect(isset($read($path)['upstream']) && !$c->publicState()['upstream_terminal_confirmed'], 'Old SSE-only flag cannot migrate into independent proof.'); [$c,$task,$path]=$make(); try{$c->bindTask('qwen','fixture-user','handoff-task','handoff-run');$expect(false,'Unexpected created task blocks');}catch(\RuntimeException $e){$expect($e->getMessage()==='UPSTREAM_TASK_HANDOFF_BLOCKED','Created handoff retained.');} $c->markTerminal('handoff-task','stopped','handoff-run'); $c->clearTask('handoff-task'); $expect($c->publicState()['upstream_pending_task_count']===2,'Handoff producer receipt cannot clear either generation.'); $c->closeGeneration('handoff-task',static fn(array $id):array=>$reply($id,'stopped')); $expect($c->publicState()['upstream_pending_task_count']===1 && isset($read($path)['upstream']), 'Handoff verification only releases its own exact pair.'); $c->signalCancel(); $c->signalTimeout(); $c->finish('error'); $expect($c->publicState()['cancel_requested'] && $c->publicState()['timeout_reached'] && $c->publicState()['status']==='cancelled', 'Original cancel/timeout intent survives lifecycle verification.'); [$c,$task,$path]=$make(); foreach(['second','third']as$suffix){try{$c->bindTask('qwen','fixture-user','handoff-'.$suffix,'run-'.$suffix);}catch(\RuntimeException $e){$expect($e->getMessage()==='UPSTREAM_TASK_HANDOFF_BLOCKED','Recovery retains another own original pair.');}} $c->finish('error');$calls=0;$timeouts=[]; $r=$c->reconcileClosedTasks(static function(array $id,int $ms)use(&$calls,&$timeouts,$reply):array{ ++$calls;$timeouts[]=$ms; $GLOBALS['r26Clock']+=($calls<=2?700:$ms)*1000000; return $reply($id,$calls<=2?'running':'succeeded'); }); $expect($calls===3 && $r['elapsed_ms']===2000 && $r['status']==='budget_exhausted' && $r['upstream_pending_task_count']===3,'Whole-request recovery retains original global two-second cap across all targets.'); $expect($timeouts[0]===1000 && $timeouts[1]===1000 && $timeouts[2]>0 && $timeouts[2]<=350,'Later target receives only original remaining I/O budget.'); $globalStart=$read($path)['closed_verification_started_at'];$GLOBALS['r26Clock']+=10000000000; $r=$c->reconcileClosedTasks(static function()use(&$calls):array{++$calls;return [];}); $expect($calls===3 && $r['budget_exhausted'] && $read($path)['closed_verification_started_at']===$globalStart,'Repeated final recovery cannot renew its global budget.'); [$c,$task,$path]=$make();$state=$read($path);$state['verification_started_at']=$GLOBALS['r26Clock']/1e9-1.8;$state['verification_attempts']=1;$write($path,$state); $r=$c->closeGeneration($task,static function(array $id,int $ms)use($expect,$reply):array{$expect($ms>0&&$ms<=200,'Per-generation close narrows an existing budget.');return $reply($id,'stopped');}); $expect($r['confirmed'] && $read($path)['verification_attempts']===2,'Existing generation verification budget is reused at EOF.'); [$c,$task,$path]=$make();$state=$read($path);$state['verification_started_at']=$GLOBALS['r26Clock']/1e9+1;$write($path,$state);$calls=0; $r=$c->closeGeneration($task,static function()use(&$calls):array{++$calls;return [];}); $expect($calls===0 && $r['reason']==='budget_exhausted' && !$c->canStartAttempt(),'Monotonic-clock reset never renews or bypasses a generation budget.'); echo "R26 per-generation lifecycle: {$checks} assertions passed (synthetic controls/clock, no network/bootstrap/model).\n"; } finally { $real=realpath($dir);$temp=realpath(sys_get_temp_dir()); if($real!==false){if($temp===false||!str_starts_with(str_replace('\\','/',$real),rtrim(str_replace('\\','/',$temp),'/').'/r26-generation-'))throw new \RuntimeException('Cleanup boundary'); foreach(new \DirectoryIterator($real)as$file){if($file->isDot())continue;if($file->isLink()||!$file->isFile())throw new \RuntimeException('Unexpected temp entry');unlink($file->getPathname());}rmdir($real);} } }