Files
zyt/server/tests/PrivateTcmR26bPendingRunInputInspectorTest.php
2026-10-27 14:03:35 +08:00

313 lines
30 KiB
PHP

<?php
declare(strict_types=1);
namespace PrivateTcmR26 {
function hrtime(bool $number=false): int { return $GLOBALS['r26InspectClock']; }
function is_link(string $path): bool {
$normalize=static fn(string $value):string=>strtolower(str_replace('\\','/',$value));
return in_array($normalize($path),array_map($normalize,$GLOBALS['r26InspectLinks']),true) || \is_link($path);
}
function curl_init(): object {
++$GLOBALS['r26InspectCalls']; $s=array_shift($GLOBALS['r26InspectScenarios']);
if (!is_array($s)) throw new \RuntimeException('Unexpected stub GET');
return (object)['scenario'=>$s,'options'=>[],'errno'=>0];
}
function curl_setopt_array(object $h,array $options): bool { $h->options=$options; $GLOBALS['r26InspectOptions'][]=$options; return true; }
function curl_exec(object $h): bool {
if (!empty($h->scenario['throw'])) throw new \RuntimeException('PRIVATE_EXCEPTION_SENTINEL');
$GLOBALS['r26InspectClock'] += $h->scenario['advance']??0; $h->errno=$h->scenario['errno']??0;
foreach ($h->scenario['chunks']??[$h->scenario['body']] as $chunk)
if (($h->options[CURLOPT_WRITEFUNCTION])($h,$chunk)!==strlen($chunk)) { $h->errno=CURLE_WRITE_ERROR; return false; }
return $h->errno===0;
}
function curl_errno(object $h): int { return $h->errno; }
function curl_getinfo(object $h,int $option): int { return $h->scenario['http']??200; }
function curl_close(object $h): void { ++$GLOBALS['r26InspectClosed']; }
}
namespace {
require dirname(__DIR__,2).'/app/artifacts/ai_concurrency/private_tcm_r26_wire_audit.php';
require dirname(__DIR__,2).'/app/artifacts/ai_concurrency/private_tcm_r26_run_input_inspector.php';
use PrivateTcmR26\RunInputInspector as Inspector;
$checks=0;$number=0;$r26InspectClock=10000000000;$r26InspectCalls=0;$r26InspectClosed=0;
$r26InspectScenarios=[];$r26InspectOptions=[];$r26InspectLinks=[];$configurationCalls=0;
$expect=static function(bool $ok,string $message)use(&$checks):void{++$checks;if(!$ok)throw new RuntimeException($message);};
$json=static fn($x):string=>json_encode($x,JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES|JSON_THROW_ON_ERROR);
$base=sys_get_temp_dir().'/tcm-r26-pending-input-test-'.bin2hex(random_bytes(8));
$root=$base.'/server';$directory=$root.'/runtime/tcm-r26-wire-audits';mkdir($directory,0700,true);
$results=$base.'/app/artifacts/ai_concurrency';mkdir($results,0700,true);
$helper=dirname(__DIR__,2).'/app/artifacts/ai_concurrency/private_tcm_r26_wire_audit.php';
$helperHash=hash_file('sha256',$helper);
$expect($helperHash==='79ca3b7c668d0a53d09299435df6a1b141ea0927f39808a9c306d301b06a89b8','Immutable r26 audit schema source pin');
$config=['enable'=>true,'base_url'=>'https://private.invalid:8443/v1/chat-messages','models'=>[
'qwen'=>['api_key'=>'PRIVATE_KEY_SENTINEL'],'openai'=>['api_key'=>'PRIVATE_OPENAI_KEY_SENTINEL']]];
$query="CASE_SENTINEL 合成原文/quoted\"\r\n尾部 é e\u{0301} 😀\\n \t";
$save=static function(array &$f)use($json):void{file_put_contents($f['result'],$json($f['document']));};
$make=static function(array $queries,array $modes=['pending'],string $profile='qwen')use(&$number,$directory,$base,$results,$json,$save):array{
$n=++$number;$uuid=sprintf('44444444-4444-4444-8444-%012d',$n);$label='owned';
$control=$base.'/synthetic-control-'.$n.'.json';
$audit=new PrivateTcmR26WireAudit($directory,$uuid,$label.'_'.$profile,$profile,$control);
$pairs=[];$pending=0;$conflict=false;$allTerminal=true;$anyStopAccepted=false;
foreach($queries as$i=>$q){
$mode=$modes[$i]??$modes[0];$task='private-task-'.$n.'-'.$i;$run='private-run-'.$n.'-'.$i;$pairs[]=[$task,$run];
$identity=$audit->observe(['protocol'=>'dify','body_sha256'=>hash('sha256','body-'.$q),'body_bytes'=>strlen('body-'.$q),
'query_sha256'=>hash('sha256',$q),'query_bytes'=>strlen($q),'inputs_sha256'=>hash('sha256','{}'),'inputs_bytes'=>2,'report_continuation_query'=>$i>0]);
$token=sprintf('%024x',$n*100+$i+1);$audit->submitted($token);
if(!in_array($mode,['unidentified','latebound'],true)){$identity($task,'');if($mode!=='task_only')$identity($task,$run);}
$terminal=in_array($mode,['terminal','no_producer'],true);$identified=!in_array($mode,['unidentified','task_only','latebound'],true);
$closed=$mode!=='open';$producer=$mode==='no_producer'?'':'stopped';$t=100+$i*10;
$record=['upstream'=>['profile'=>$profile,'generation'=>$i+1,'submission_id'=>$token,'task_id'=>$task,'workflow_run_id'=>$run],
'producer_terminal_status'=>$producer,'producer_terminal_observed_at'=>$producer===''?null:$t,
'persisted_run_status'=>'','persisted_run_observed_at'=>null,'persisted_terminal_confirmed'=>false,'upstream_terminal_confirmed'=>false,
'transfer_closed'=>false,'transfer_closed_at'=>null,'lifecycle_conflict'=>false,
'upstream_stop_confirmed'=>$producer!=='','stop_accepted_at'=>$producer===''?null:$t+0.1,
'verification_attempts'=>0,'verification_started_at'=>null,'generation_verification_elapsed_ms'=>0,'run_status_observations'=>[]];
$submission=['profile'=>$profile,'task_id'=>$mode==='unidentified'?'':$task,'workflow_run_id'=>!$identified?'':$run,
'submitted_at'=>$t-1,'transfer_closed'=>false,'disposition'=>'unconfirmed'];
$record['submitted_attempts']=[$token=>$submission];
if($identified){file_put_contents($control,$json($record));$audit->captureControl($task);}
if($closed)$audit->transferClosed($i+1,['transport_closed_ms'=>5,'transport_exit'=>'natural_eof'],10.0+$i*10);
if($mode==='latebound'){$identity($task,$run);$identified=true;}
if($identified&&$closed){
$record['transfer_closed']=true;$record['transfer_closed_at']=$t+0.2;
$record['persisted_run_status']=$terminal?'stopped':'running';$record['persisted_run_observed_at']=$t+0.4;
$record['persisted_terminal_confirmed']=$terminal;$record['upstream_terminal_confirmed']=$terminal;
$record['lifecycle_conflict']=!$terminal&&$producer!=='';$record['verification_attempts']=1;
$record['verification_started_at']=$t+0.3;$record['generation_verification_elapsed_ms']=100;
$record['run_status_observations']=[['status'=>$terminal?'stopped':'running','observed_at'=>$t+0.4,'within_budget'=>true]];
if($mode==='zero_attempt'){
$record['persisted_run_status']='';$record['persisted_run_observed_at']=null;$record['run_status_observations']=[];
$record['verification_attempts']=0;$record['generation_verification_elapsed_ms']=2000;$record['lifecycle_conflict']=false;
}
$submission['transfer_closed']=true;$submission['transfer_closed_at']=$t+0.2;
$record['submitted_attempts']=[$token=>$submission];
file_put_contents($control,$json($record));$audit->captureControl($task);
}
if($closed){$audit->submissionClosed($token,$mode==='unidentified'?'':$task,'unconfirmed',10.0+$i*10);
if(!$identified){$submission['transfer_closed']=true;$submission['transfer_closed_at']=$t+0.2;file_put_contents($control,$json(['submitted_attempts'=>[$token=>$submission]]));$audit->captureControl();}}
$allTerminal=$allTerminal&&$terminal&&$identified&&$closed;
if(!$terminal)++$pending;
$conflict=$conflict||($identified&&$closed&&!$terminal&&$producer!==''&&$mode!=='zero_attempt');
$anyStopAccepted=$anyStopAccepted||($identified&&$producer!=='');
}
$state=['transport_closed'=>!in_array('open',$modes,true),'upstream_terminal_confirmed'=>$allTerminal,
'upstream_stop_confirmed'=>$anyStopAccepted,'cancel_requested'=>false,'timeout_reached'=>false,'lifecycle_conflict'=>$conflict,'upstream_pending_task_count'=>$pending,
'submitted_attempt_count'=>count($queries),'submitted_transfer_closed_count'=>count($queries)-(int)in_array('open',$modes,true),
'submitted_pending_attempt_count'=>$pending,'submitted_without_identity_count'=>count(array_filter($modes,static fn($v)=>in_array($v,['unidentified','task_only'],true))),
'pre_execution_closed_attempt_count'=>0,'not_submitted_attempt_count'=>0,'rejected_before_execution_attempt_count'=>0];
$summary=$audit->finish($state);
$row=['harness_contract'=>'v43r26_private_run_wire','synthetic'=>true,'preparation_isolated'=>true,'preparation_isolation_verified'=>true,
'production_acceptance_path'=>true,'diagnostic_only'=>false,'case_id'=>11,'test_label'=>$label,'profile'=>$profile,
'production_hashes'=>['fixture'=>'b54c47ec11f6a99dc87bdda78629e18c8a6f37a64017e42a72db399c727cb1c6',
'question'=>'28fbaee8585d4fbde3be3b1a6ee046c1a60f18a1fe67c0769211b08afdd5d306'],
'private_wire_audit'=>$summary,'private_wire_audit_verified'=>true,'cleanup_independently_confirmed'=>$summary['independent_cleanup_confirmed'],
'state'=>$state,'terminal_recovery_after_state'=>$state];
$document=['harness_contract'=>'v43r26_private_run_wire','synthetic_only'=>true,'preparation_isolated'=>true,
'fixture_sha256'=>$row['production_hashes']['fixture'],'canonical_question_sha256'=>$row['production_hashes']['question'],'rows'=>[$row]];
$f=['audit'=>$directory.'/'.hash('sha256',$uuid).'.private.jsonl','control'=>$control,'document'=>$document,
'result'=>$results.'/tcm_complete_r26_fixture_'.$n.'.safe.json','pairs'=>$pairs,'queries'=>$queries];
$save($f);return$f;
};
$select=static fn(array $f):array=>['result_file'=>basename($f['result']),'test_label'=>'owned',
'profile'=>$f['document']['rows'][0]['profile'],'audit_sha256'=>$f['document']['rows'][0]['private_wire_audit']['audit_sha256']];
$response=static function(array $f,int $n=0,string $status='running',bool $serialized=true)use($json):array{
$inputs=['sys.query'=>$f['queries'][$n]];
return ['id'=>$f['pairs'][$n][1],'status'=>$status,'inputs'=>$serialized?$json($inputs):$inputs,'outputs'=>['PRIVATE_OUTPUT_SENTINEL'=>'PRIVATE_BODY_SENTINEL']];
};
$run=static function(array $f,array $scenarios,?array $cfg=null,?array $selector=null)use($root,$select,$config,&$configurationCalls):array{
$GLOBALS['r26InspectScenarios']=$scenarios;
return Inspector::inspectResultRow($root,$selector??$select($f),static function()use($cfg,$config,&$configurationCalls):array{++$configurationCalls;return$cfg??$config;});
};
$rewrite=static function(array &$f,callable $mutation)use($json,$save):void{
$rows=array_map(static fn($s)=>json_decode($s,true,16,JSON_THROW_ON_ERROR),file($f['audit'],FILE_IGNORE_NEW_LINES));
$mutation($rows,$f['document']);
$raw=implode("\n",array_map($json,$rows))."\n";file_put_contents($f['audit'],$raw);
$f['document']['rows'][0]['private_wire_audit']['audit_bytes']=strlen($raw);
$f['document']['rows'][0]['private_wire_audit']['audit_sha256']=hash('sha256',$raw);$save($f);
};
$privacy=static function(array $answer)use($expect,$json):void{
$safe=$json($answer);
foreach(['private-task','private-run','PRIVATE_KEY','PRIVATE_OPENAI_KEY','PRIVATE_OUTPUT','PRIVATE_BODY','PRIVATE_EXCEPTION','CASE_SENTINEL','private.invalid','owned','synthetic-control']as$v)
$expect(!str_contains($safe,$v),'Safe output excludes private data: '.$v);
};
try{
foreach(['pending','zero_attempt','terminal','no_producer']as$mode){
$f=$make([$query],[$mode]);$original=[];
$isPending=in_array($mode,['pending','zero_attempt'],true);
foreach(['audit','control','result']as$k)$original[$k]=hash_file('sha256',$f[$k]);
$answer=$run($f,[['body'=>$json($response($f,0,$isPending?'running':'stopped'))]]);
$expect($answer['ok']&&$answer['matched_run_count']===1&&$answer['runs'][0]['returned_run_id_matches'],'Exact saved own r26 row/pair/query is eligible: '.$mode);
$expect($answer['saved_pending_generation_count']===($isPending?1:0)
&&$answer['saved_independent_cleanup_confirmed']===!$isPending
&&$answer['authoritative_control_mutated']===false,'Pending durability and independent terminal remain separate: '.$mode);
$expect($answer['runs'][0]['run_status']===($isPending?'running':'stopped')&&$answer['runs'][0]['inputs_encoding']==='json_string','Returned running stays running: '.$mode);
foreach($original as$k=>$v)$expect(hash_file('sha256',$f[$k])===$v,'GET-only inspector leaves synthetic original evidence/control unchanged: '.$k);
$privacy($answer);
}
$f=$make([$query,$query.'续写'],['terminal','pending']);
$answer=$run($f,[['body'=>$json($response($f,0,'stopped',false))],['body'=>$json($response($f,1,'running'))]]);
$expect($answer['ok']&&$answer['inspected_run_count']===2&&$answer['saved_pending_generation_count']===1,'Two original generations with different outcomes remain distinct');
$expect($answer['runs'][0]['inputs_encoding']==='object'&&$answer['runs'][1]['inputs_encoding']==='json_string','Both accepted input encodings');
$f=$make([$query],['pending']);$controlHash=hash_file('sha256',$f['control']);
$answer=$run($f,[['body'=>$json($response($f,0,'stopped'))]]);
$expect($answer['ok']&&$answer['runs'][0]['run_status']==='stopped'&&$answer['saved_pending_generation_count']===1
&&$answer['saved_independent_cleanup_confirmed']===false&&hash_file('sha256',$f['control'])===$controlHash,
'Fresh terminal observation cannot mutate or promote authoritative saved pending state');
$f=$make([$query],['pending']);$f['document']['rows'][0]['state']['transport_closed']=false;$f['document']['rows'][0]['terminal_recovery_after_state']=$f['document']['rows'][0]['state'];
$rewrite($f,static function(&$rows):void{$rows[count($rows)-1]['state']['transport_closed']=false;});
$answer=$run($f,[['body'=>$json($response($f))]]);
$expect($answer['ok'],'Own closed generation eligibility does not circularly require whole-request terminal or closed flag');
$f=$make([$query],['terminal']);$f['document']['rows'][0]['state']['transport_closed']=false;
$f['document']['rows'][0]['terminal_recovery_after_state']=$f['document']['rows'][0]['state'];
$f['document']['rows'][0]['cleanup_independently_confirmed']=false;
$rewrite($f,static function(&$rows):void{$rows[count($rows)-1]['state']['transport_closed']=false;});
$answer=$run($f,[['body'=>$json($response($f,0,'stopped'))]]);
$expect($answer['ok']&&$answer['saved_audit_independent_cleanup_confirmed']===true
&&$answer['saved_independent_cleanup_confirmed']===false,'Audit generation proof and final whole-request cleanup flag retain their distinct driver meanings');
foreach(['unidentified','task_only','open','latebound']as$mode){
$f=$make([$query],[$mode]);$before=$r26InspectCalls;$beforeConfig=$configurationCalls;$answer=$run($f,[]);
$expect(!$answer['ok']&&$r26InspectCalls===$before&&$configurationCalls===$beforeConfig,'No GET/config without complete original pair and own generation closure: '.$mode);
}
foreach(['false_terminal','foreign_closure','negative_clock','closure_duration','duplicate_eof','duplicate_identity','duplicate_lifecycle','duplicate_reordered_lifecycle',
'foreign_producer','wrong_control_generation','foreign_source','wrong_event_generation','missing_eof','missing_lifecycle','partial',
'unknown_event','extra_raw','bad_time','late_observation','late_terminal','time_regression','changed_producer','count_mismatch','footer_mismatch',
'summary_lifecycle','false_consistent','false_cleanup','wrong_uuid','wrong_label','wrong_profile','missing_newline','bad_record_json']as$kind){
$f=$make([$query],['pending']);
$rewrite($f,static function(&$rows,&$doc)use($kind):void{
$last=count($rows)-1;$life=[];$eof=null;$identity=null;
foreach($rows as$i=>$r){if($r['event']==='generation_lifecycle')$life[]=$i;if($r['event']==='generation_transfer_closed')$eof=$i;if($r['event']==='original_identity')$identity=$i;}
$l=end($life);
if($kind==='false_terminal'){
$rows[$l]['state']['independently_terminal']=true;
$doc['rows'][0]['private_wire_audit']['generations'][0]['independently_terminal']=true;
$doc['rows'][0]['private_wire_audit']['generations'][0]['lifecycle']['independently_terminal']=true;
}
if($kind==='foreign_closure')$rows[$eof]['original_workflow_run_id']='foreign-run';
if($kind==='negative_clock')$rows[$eof]['at_request_ms']=-1;
if($kind==='closure_duration')$rows[$eof]['transport_closed_ms']=99999;
if($kind==='duplicate_eof')array_splice($rows,$last,0,[$rows[$eof]]);
if($kind==='duplicate_identity')array_splice($rows,$identity+1,0,[$rows[$identity]]);
if($kind==='duplicate_lifecycle')array_splice($rows,$last,0,[$rows[$l]]);
if($kind==='duplicate_reordered_lifecycle'){$copy=$rows[$l];$copy['state']=array_reverse($copy['state'],true);array_splice($rows,$last,0,[$copy]);}
if($kind==='foreign_producer')$rows[$life[0]]['original_task_id']='foreign-task';
if($kind==='wrong_control_generation')$rows[$l]['control_generation']=99;
if($kind==='foreign_source')$rows[$l]['source']='neighbor_control';
if($kind==='wrong_event_generation')$rows[$eof]['generation']=2;
if($kind==='missing_eof')array_splice($rows,$eof,1);
if($kind==='missing_lifecycle')foreach(array_reverse($life)as$i)array_splice($rows,$i,1);
if($kind==='partial')array_pop($rows);
if($kind==='unknown_event')$rows[$l]['event']='raw_provider_body';
if($kind==='extra_raw')$rows[$l]['state']['raw_body']='PRIVATE_BODY_SENTINEL';
if($kind==='bad_time')$rows[$l]['state']['producer_terminal_observed_at']='100';
if($kind==='late_observation'){$rows[$l]['state']['observations'][0]['observed_at']=103;$rows[$l]['state']['persisted_run_observed_at']=103;}
if($kind==='late_terminal'){$rows[$l]['state']['independently_terminal']=true;$rows[$l]['state']['persisted_run_status']='stopped';$rows[$l]['state']['observations'][0]['status']='stopped';$rows[$l]['state']['observations'][0]['within_budget']=false;}
if($kind==='time_regression')$rows[$l]['state']['producer_terminal_observed_at']=99;
if($kind==='changed_producer')$rows[$l]['state']['producer_terminal_status']='failed';
if($kind==='count_mismatch')++$doc['rows'][0]['private_wire_audit']['original_run_count'];
if($kind==='footer_mismatch')$rows[$last]['state']['upstream_pending_task_count']=0;
if($kind==='summary_lifecycle')$doc['rows'][0]['private_wire_audit']['generations'][0]['lifecycle']['stop_accepted']=false;
if($kind==='false_consistent')$rows[$last]['lifecycle_consistent']=false;
if($kind==='false_cleanup'){$rows[$last]['state']['upstream_terminal_confirmed']=true;$doc['rows'][0]['state']['upstream_terminal_confirmed']=true;$doc['rows'][0]['terminal_recovery_after_state']=$doc['rows'][0]['state'];}
if($kind==='wrong_uuid')$rows[0]['request_id']='55555555-5555-4555-8555-555555555555';
if($kind==='wrong_label')$rows[0]['request_label']='neighbor_qwen';
if($kind==='wrong_profile')$rows[0]['profile']='openai';
});
if(in_array($kind,['missing_newline','bad_record_json'],true)){
$raw=file_get_contents($f['audit']);$raw=$kind==='missing_newline'?rtrim($raw,"\n"):"{\n";
file_put_contents($f['audit'],$raw);$f['document']['rows'][0]['private_wire_audit']['audit_bytes']=strlen($raw);
$f['document']['rows'][0]['private_wire_audit']['audit_sha256']=hash('sha256',$raw);$save($f);
}
$before=$r26InspectCalls;$beforeConfig=$configurationCalls;$answer=$run($f,[]);
$expect(!$answer['ok']&&$r26InspectCalls===$before&&$configurationCalls===$beforeConfig,'Invalid audit fails before config/GET: '.$kind);$privacy($answer);
}
foreach(['foreign_case','old_contract','wrong_fixture','duplicate_row','named_rows','row_missing','row_state','recovery_state','unverified','cleanup_flag','digest','path','extra_selector']as$kind){
$f=$make([$query]);$selector=$select($f);
if($kind==='foreign_case')$f['document']['rows'][0]['case_id']=12;
if($kind==='old_contract')$f['document']['harness_contract']='v43r25_private_run_wire';
if($kind==='wrong_fixture')$f['document']['fixture_sha256']=str_repeat('a',64);
if($kind==='duplicate_row')$f['document']['rows'][]=$f['document']['rows'][0];
if($kind==='named_rows')$f['document']['rows']=['named'=>$f['document']['rows'][0]];
if($kind==='row_missing')$selector['test_label']='neighbor';
if($kind==='row_state'){$f['document']['rows'][0]['state']['lifecycle_conflict']=false;$f['document']['rows'][0]['terminal_recovery_after_state']=$f['document']['rows'][0]['state'];}
if($kind==='recovery_state')$f['document']['rows'][0]['terminal_recovery_after_state']=[];
if($kind==='unverified')$f['document']['rows'][0]['private_wire_audit_verified']=false;
if($kind==='cleanup_flag')$f['document']['rows'][0]['cleanup_independently_confirmed']=true;
if($kind==='digest')$selector['audit_sha256']=str_repeat('a',64);
if($kind==='path')$selector['result_file']='../'.basename($f['result']);
if($kind==='extra_selector')$selector['run']='private-run-override';
$save($f);$before=$r26InspectCalls;$beforeConfig=$configurationCalls;$answer=$run($f,[],null,$selector);
$expect(!$answer['ok']&&$r26InspectCalls===$before&&$configurationCalls===$beforeConfig,'Saved selected row boundary: '.$kind);
}
$f=$make([$query]);$r26InspectLinks=[$f['result']];$before=$r26InspectCalls;$answer=$run($f,[]);
$expect(!$answer['ok']&&$r26InspectCalls===$before,'Result symlink branch rejects before GET (namespaced filesystem-boundary stub)');$r26InspectLinks=[];
$r26InspectLinks=[$f['audit']];$before=$r26InspectCalls;$answer=$run($f,[]);
$expect(!$answer['ok']&&$r26InspectCalls===$before,'Audit symlink branch rejects before GET (namespaced filesystem-boundary stub)');$r26InspectLinks=[];
$duplicate=$directory.'/'.str_repeat('f',64).'.private.jsonl';copy($f['audit'],$duplicate);$before=$r26InspectCalls;$answer=$run($f,[]);
$expect(!$answer['ok']&&$answer['status']==='audit_digest_ambiguous'&&$r26InspectCalls===$before,'Duplicate exact digest never picks a neighboring file');unlink($duplicate);
$f=$make([$query,$query,$query],['pending']);$before=$r26InspectCalls;$answer=$run($f,[]);
$expect(!$answer['ok']&&$answer['status']==='original_run_limit'&&$r26InspectCalls===$before,'At most two original runs, no partial selection');
$f=$make([$query],['no_producer']);
$rewrite($f,static function(&$rows,&$doc):void{
$rows[count($rows)-1]['state']['upstream_stop_confirmed']=true;
$doc['rows'][0]['state']['upstream_stop_confirmed']=true;$doc['rows'][0]['terminal_recovery_after_state']=$doc['rows'][0]['state'];
});
$before=$r26InspectCalls;$beforeConfig=$configurationCalls;$answer=$run($f,[]);
$expect(!$answer['ok']&&$r26InspectCalls===$before&&$configurationCalls===$beforeConfig,'Footer cannot invent a stop acceptance absent from every generation');
$f=$make([$query]);
foreach(['object','serialized','same_aliases','alias_conflict','bad_alias','nested','missing','malformed','recursive','array','deep','wrong_id','changed_bytes','unpaired_surrogate']as$kind){
$value=$response($f);$expected=in_array($kind,['object','serialized','same_aliases'],true);
if($kind==='object')$value['inputs']=['query'=>$query];
if($kind==='same_aliases')$value['inputs']=$json(['query'=>$query,'sys.query'=>$query]);
if($kind==='alias_conflict')$value['inputs']=$json(['query'=>$query,'sys.query'=>'different']);
if($kind==='bad_alias')$value['inputs']=$json(['query'=>$query,'sys.query'=>null]);
if($kind==='nested')$value['inputs']=$json(['nested'=>['query'=>$query]]);
if($kind==='missing')unset($value['inputs']);
if($kind==='malformed')$value['inputs']='{PRIVATE_BODY_SENTINEL';
if($kind==='recursive')$value['inputs']=$json($json(['query'=>$query]));
if($kind==='array')$value['inputs']='[]';
if($kind==='deep')$value['inputs']=str_repeat('{"x":',65).'0'.str_repeat('}',65);
if($kind==='wrong_id')$value['id']='foreign-run';
if($kind==='changed_bytes')$value['inputs']=$json(['query'=>str_replace("\r\n","\n",$query)]);
if($kind==='unpaired_surrogate')$value['inputs']='{"query":"\uD800"}';
$answer=$run($f,[['body'=>$json($value)]]);$expect($answer['ok']===$expected,'Bounded exact inputs decoding: '.$kind);
$expect($answer['runs'][0]['returned_run_id_matches']===($kind!=='wrong_id'),'Returned id independent of query availability: '.$kind);$privacy($answer);
}
foreach(['redirect','transport','throw','timeout','oversize','invalid_json']as$kind){
$scenario=['body'=>$json($response($f))];
if($kind==='redirect')$scenario['http']=302;if($kind==='transport')$scenario['errno']=60;if($kind==='throw')$scenario['throw']=true;
if($kind==='timeout')$scenario['advance']=2000000000;if($kind==='oversize')$scenario['body']=str_repeat('x',2097153);if($kind==='invalid_json')$scenario['body']='{';
$before=$r26InspectCalls;$answer=$run($f,[$scenario]);$expect(!$answer['ok']&&$r26InspectCalls===$before+1,'Bounded transport failure without fallback: '.$kind);$privacy($answer);
}
$http=$config;$http['base_url']='http://private.invalid:8088/v1/chat-messages';
$answer=$run($f,[['body'=>$json($response($f))]],$http);$options=end($r26InspectOptions);
$expect($answer['ok']&&$options[CURLOPT_PROTOCOLS]===CURLPROTO_HTTP&&$options[CURLOPT_REDIR_PROTOCOLS]===CURLPROTO_HTTP,'Exactly configured HTTP scheme retained');
$expect($options[CURLOPT_URL]==='http://private.invalid:8088/v1/workflows/run/'.$f['pairs'][0][1],'Exact configured original endpoint only');
foreach($r26InspectOptions as$options){
$expect($options[CURLOPT_HTTPGET]===true&&!isset($options[CURLOPT_POSTFIELDS])&&!isset($options[CURLOPT_POST]),'GET only');
$expect($options[CURLOPT_SSL_VERIFYPEER]===true&&$options[CURLOPT_SSL_VERIFYHOST]===2&&$options[CURLOPT_FOLLOWLOCATION]===false&&$options[CURLOPT_MAXREDIRS]===0,'TLS verified, no redirect');
$expect($options[CURLOPT_PROXY]===''&&$options[CURLOPT_NOPROXY]==='*'&&$options[CURLOPT_NETRC]===CURL_NETRC_IGNORED,'No environment proxy/netrc');
$expect($options[CURLOPT_TIMEOUT_MS]>0&&$options[CURLOPT_TIMEOUT_MS]<=2000,'At most two seconds per run');
}
$artifact=dirname(__DIR__,2).'/app/artifacts/ai_concurrency/';
$probe=file_get_contents($artifact.'private_tcm_r26_run_input_probe.php');
$old=file_get_contents($artifact.'private_tcm_r25b_run_input_probe.php');
$expected=str_replace(['PrivateTcmR25b','private_tcm_r25b_run_input_','runInputR25bFinish','// New r25b derivative; the original r25 probe/helper remain immutable.'],
['PrivateTcmR26','private_tcm_r26_run_input_','runInputR26Finish','// New r26 derivative; all original r25/r25b probes/helpers remain immutable.'],str_replace("\r\n","\n",$old));
$expect($probe===$expected,'Canonical seven-key auth/permission bridge exactly retained except derivative names/comment');
$new=file_get_contents($artifact.'private_tcm_r26_run_input_inspector.php');$old=file_get_contents($artifact.'private_tcm_r25b_run_input_inspector.php');
$expect(substr($new,strpos($new,' private static function connection('))===substr(str_replace("\r\n","\n",$old),strpos(str_replace("\r\n","\n",$old),' private static function connection(')),'Accepted r25b same-scheme GET/JSON decoder transport copied exactly');
$expect(!(new ReflectionMethod(Inspector::class,'inspect'))->isPublic(),'No public low-level saved-row bypass');
foreach(['think\\App','think\\facade\\Db','think\\facade\\Config','app\\adminapi\\service\\AssistantRequestControl','app\\common\\service\\DifyChatService']as$class)
$expect(!class_exists($class,false),'No framework/control/provider bootstrap: '.$class);
$expect(hash_file('sha256',$helper)===$helperHash,'Current immutable harness helper unchanged');
$expect($r26InspectCalls===$r26InspectClosed&&$r26InspectScenarios===[],'All fake handles closed and only declared stub GETs consumed');
echo "Private r26b pending run input inspector: {$checks} checks passed; pure temporary evidence/cURL/time/path stubs, no real auth/network/bootstrap/config/runtime/GET/stop/model.\n";
}finally{
$real=realpath($base);$temp=realpath(sys_get_temp_dir());
if($real!==false){if($temp===false||!str_starts_with(str_replace('\\','/',$real),rtrim(str_replace('\\','/',$temp),'/').'/tcm-r26-pending-input-test-'))throw new RuntimeException('Cleanup boundary');
$it=new RecursiveIteratorIterator(new RecursiveDirectoryIterator($real,FilesystemIterator::SKIP_DOTS),RecursiveIteratorIterator::CHILD_FIRST);
foreach($it as$f){if($f->isLink())throw new RuntimeException('Unexpected symlink');$f->isDir()?rmdir($f->getPathname()):unlink($f->getPathname());}rmdir($real);}
}
}