match_runner.py
python · 403 lines · Sanitized derivative
Sanitized derivative: private paths or personal test identities use explicit placeholders. Original line count is preserved.
Version & provenance · evaluation-cm7
Recorded SHA-256 31f850e58b023bb47b5ac186625e1396727b87d2c72234438b50802e2ff381d7Rendered SHA-256 13789307a99daaeac51089f8e7264417f565f1a66d293ff57bdcd48bf3b68d0a
Apache-2.0 original project code; dependencies retain their own licenses. License notes. Line links are stable within this snapshot. CM-7 completed implementation source; original and public rendered hashes recorded. Host-specific paths use /work placeholders; inspect reproduction instructions before running. Separate Rust helper retains its GPL license.
1"""Frozen-suite runner. Default is plan-only; matches require a reviewed release.
2
3Existing model/harness/serving files are read-only. Linux guardian owns the match
4worker/model group; detached UCI children additionally die with their parent.
5"""
6import argparse,ctypes,hashlib,importlib.util,io,json,math,os,re,signal,subprocess,sys,time,uuid
7from pathlib import Path
8
9def engine_child(parent,command):
10 """Contain the engine before importing project packages or executing it."""
11 if os.name!='posix':raise RuntimeError('Linux parent-death handling required')
12 if ctypes.CDLL(None,use_errno=True).prctl(1,signal.SIGKILL,0,0,0)!=0:raise OSError(ctypes.get_errno(),'PDEATHSIG failed')
13 if os.getppid()!=parent:raise RuntimeError('engine parent disappeared before initialization')
14 os.execv(command[0],command)
15
16if __name__=='__main__' and sys.argv[1:2]==['--engine-child']:
17 engine_child(int(sys.argv[2]),sys.argv[3:])
18
19ROOT=Path(__file__).resolve().parent
20PROJECT=ROOT.parent
21HARNESS_ROOT=ROOT
22SUNFISH_ROOT=PROJECT.parent.parent/'task-16'
23GUARDIAN_PATH=(PROJECT/'scaleup-v1/runtime/training_deadline.py').resolve()
24MODEL_METRICS={'raw_greedy_tokens','raw_greedy_legal','legal_joint_probability',
25 'illegal_or_nonmove_three_token_probability','selected_joint_log_probability','forward_calls'}
26APPROVAL_KEYS={'approved','run_id','run_directory','suite_sha256','execution_contract_sha256','runner_sha256','guardian_sha256','checkpoint','checkpoint_sha256','dataset_manifest','dataset_manifest_sha256','device','role','budget_seconds'}
27sys.path[:0]=[str(PROJECT),str(HARNESS_ROOT),str(PROJECT/'scaleup-v1/runtime')]
28# Make only the existing pure-Python chess package visible in spawned model workers.
29if importlib.util.find_spec('chess') is None:
30 package=Path('/work/.cache/pypoetry/virtualenvs/rulebound-LLUAbKSL-py3.11/lib/python3.11/site-packages/chess')
31 spec=importlib.util.spec_from_file_location('chess',package/'__init__.py',submodule_search_locations=[str(package)])
32 module=importlib.util.module_from_spec(spec);sys.modules['chess']=module;spec.loader.exec_module(module)
33
34def sha(path):
35 h=hashlib.sha256()
36 with Path(path).open('rb') as stream:
37 while block:=stream.read(8*1024*1024):h.update(block)
38 return h.hexdigest()
39
40def load_guardian(expected_hash=None):
41 """Load exactly the approved file, independent of sys.path/sys.modules."""
42 path=GUARDIAN_PATH.resolve()
43 source=path.read_bytes()
44 if expected_hash is not None and hashlib.sha256(source).hexdigest()!=expected_hash:raise ValueError('approved guardian changed')
45 spec=importlib.util.spec_from_file_location('_chess_match_guardian_'+uuid.uuid4().hex,path)
46 module=importlib.util.module_from_spec(spec);exec(compile(source,str(path),'exec'),module.__dict__)
47 if Path(module.__file__).resolve()!=path:raise RuntimeError('guardian module identity mismatch')
48 return module
49
50def require_guardian():
51 if os.environ.get('CHESS_MATCH_GUARDED')!='1' or os.getpgrp()!=os.getpid():raise RuntimeError('match worker requires its guardian-owned process group')
52 parent_command=Path(f'/proc/{os.getppid()}/cmdline').read_bytes().split(b'\0')
53 if str(GUARDIAN_PATH).encode() not in parent_command or b'--guardian' not in parent_command:
54 raise RuntimeError('match worker parent is not the approved guardian')
55
56def model_metrics(row,board):
57 """Raw model rows cannot evade denominators or omit probability diagnostics."""
58 import chess
59 if row.get('model_query')!='queried' or not MODEL_METRICS.issubset(row):raise ValueError('model policy requires queried and complete raw metrics')
60 raw=row['raw_greedy_tokens']
61 if not isinstance(raw,list) or len(raw)!=3 or any(type(t)is not int or not 0<=t<512 for t in raw):raise ValueError('invalid raw greedy tokens')
62 if type(row['raw_greedy_legal'])is not bool:raise ValueError('invalid raw legality flag')
63 promotions={None:64,chess.KNIGHT:65,chess.BISHOP:66,chess.ROOK:67,chess.QUEEN:68}
64 legal=any(raw==[m.from_square,m.to_square,promotions[m.promotion]] for m in board.legal_moves)
65 if row['raw_greedy_legal']!=legal:raise ValueError('raw greedy legality disagrees with board')
66 for key in ('legal_joint_probability','illegal_or_nonmove_three_token_probability','selected_joint_log_probability'):
67 if type(row[key])not in (int,float) or not math.isfinite(row[key]):raise ValueError('invalid raw model metrics')
68 mass=row['legal_joint_probability'];illegal=row['illegal_or_nonmove_three_token_probability']
69 if not 0<=mass<=1+1e-8 or not 0<=illegal<=1+1e-8 or abs(illegal-max(0.,1.-mass))>1e-8:raise ValueError('invalid probability mass accounting')
70 if row['selected_joint_log_probability']>1e-8:raise ValueError('invalid selected log probability')
71 if type(row['forward_calls'])is not int or row['forward_calls']<1:raise ValueError('invalid forward-call count')
72def write(path,value):
73 path=Path(path);tmp=path.with_name(path.name+'.tmp')
74 with tmp.open('w',encoding='utf-8') as stream:
75 stream.write(value if isinstance(value,str) else json.dumps(value,indent=2));stream.flush();os.fsync(stream.fileno())
76 tmp.replace(path)
77def inputs():
78 freeze=json.loads((PROJECT/'scaleup-v1/evaluation-suite/frozen-v1/freeze.json').read_text())
79 contract=json.loads((ROOT/'execution-contract.json').read_text())
80 if sha(PROJECT/'scaleup-v1/evaluation-suite/frozen-v1/suite.json')!=freeze['suite_sha256'] or contract['suite_sha256']!=freeze['suite_sha256']:
81 raise ValueError('frozen suite hash mismatch')
82 suite=json.loads((PROJECT/'scaleup-v1/evaluation-suite/frozen-v1/suite.json').read_text(encoding='utf-8'))
83 subset=contract.get('diagnostic_subset')
84 if subset is not None:
85 plan=json.loads((PROJECT/'cm7-evaluation/mini-plan.json').read_text())
86 if subset!=plan['opening_ids'] or contract.get('diagnostic_milestone') not in plan['milestones']:raise ValueError('undeclared diagnostic mini-suite')
87 suite['openings']=[o for o in suite['openings'] if o['opening_id'] in subset]
88 suite['schedule']=[g for g in suite['schedule'] if g['opening_id'] in subset]
89 if len(suite['openings'])!=5 or len(suite['schedule'])!=10:raise ValueError('diagnostic subset size')
90 suite['protocol']['diagnostic_only']=True
91 suite['protocol']['checkpoint_selection_effect']='none; noisy ten-game diagnostic, no Elo or promotion'
92 suite['protocol'].update(
93 context='state-v2 structured board/side/castling/en-passant/halfmove state plus optional genuine last16 plies; 120 prompt slots, 122 maximum model input slots; fixed position IDs and masked left history padding; 1024 allocated position rows',
94 decoding='full legal-move joint argmax, UCI lexical tie break; unmasked raw512 conditional probabilities and raw greedy diagnostics logged separately',
95 inference_precision='GPU BF16 autocast with FP32 model weights and FP32 output-logit conversion; CPU preflight uses FP32',
96 helper='Rust adaptive iterative 1/3/5/7-ply forced-mate override with verified all-defenses proof',
97 helper_seconds=.25,helper_max_plies=7,helper_workers=4,system_comparison=True,
98 comparison='system-level historical comparison: same frozen openings/colors/seeds and Sunfish budgets; representation, decoder execution, precision and helper may differ; not an isolated model-gain comparison',
99 autoplay='all prefix plies retained from standard start in authoritative board/repetition history and PGN; model sees current structured state and at most last16 genuine plies; book autoplay excluded from model legality, query and latency metrics',
100 checkpoints=['selected_state_v2_best_candidate'],
101 baseline_checkpoint_role='historical original-suite reference only; not loaded or rerun in this evaluation',
102 model_prompt_slots=120,model_max_input_slots=122,model_position_allocation=1024,
103 explicit_history_max_plies=16,raw_probability_classes=512,
104 launch_gate='independent adapter/runner/budget review, parent release and fresh GPU availability; bounded legal-decoding preflight before matches')
105 if subset is not None:
106 suite['protocol']['comparison']='predeclared ten-game checkpoint diagnostic with identical subset, colors, seeds, engine and helper; noisy and not used for selection, Elo or promotion'
107 suite['protocol']['games_per_checkpoint']=10
108 suite['protocol']['proposed_match_job_walltime_seconds_per_checkpoint']=600
109 suite['protocol']['checkpoints']=[contract['diagnostic_milestone']]
110 return suite,contract
111def verify_sources(contract):
112 for name,expected in contract['source_hashes'].items():
113 if sha(Path(name))!=expected:raise ValueError('execution source changed: '+name)
114 git=['git','-c','core.autocrlf=true','-c','core.filemode=false','-C',str(SUNFISH_ROOT/'sunfish')]
115 if subprocess.check_output(git+['rev-parse','HEAD'],text=True).strip()!=contract['sunfish_commit']:
116 raise ValueError('Sunfish commit changed')
117 if subprocess.check_output(git+['status','--porcelain'],text=True).strip():raise ValueError('Sunfish checkout modified')
118
119def proof_check(h,board,proof,color,depth=0):
120 import chess
121 if depth>7 or board.fen()!=proof['fen']:raise ValueError('bad mate proof state')
122 if proof['kind']=='checkmate':
123 if not board.is_checkmate() or board.turn==color:raise ValueError('false mate proof')
124 return
125 if depth>=7 or h.outcome(board) is not None:raise ValueError('mate proof crosses end/depth')
126 branches=proof['branches']
127 if board.turn!=color:
128 if sorted(x['move'] for x in branches)!=sorted(m.uci() for m in board.legal_moves):raise ValueError('missing defender proof branch')
129 elif len(branches)!=1:raise ValueError('invalid attacker proof branch')
130 for branch in branches:
131 move=chess.Move.from_uci(branch['move'])
132 if move not in board.legal_moves:raise ValueError('illegal proof move')
133 board.push(move)
134 try:proof_check(h,board,branch['child'],color,depth+1)
135 finally:board.pop()
136
137def audit(h,folder,report,opening,color):
138 import chess,chess.pgn
139 with (folder/'game.pgn').open(encoding='utf-8') as stream:game=chess.pgn.read_game(stream)
140 if game is None or game.errors:raise ValueError('invalid played PGN')
141 moves=list(game.mainline_moves());n=opening['autoplay_plies']
142 if [m.uci() for m in moves[:n]]!=opening['uci'] or len(moves)!=report['plies']:raise ValueError('autoplay/ply count mismatch')
143 rows=report['moves'];by_ply={r['ply']:r for r in rows}
144 if len(by_ply)!=len(rows) or set(by_ply)!=set(range(n+1,len(moves)+1)):raise ValueError('book moves included in metrics or missing played moves')
145 board=chess.Board();queried=[];overrides=0;model_turn_seconds=0.;searches=[]
146 for ply,move in enumerate(moves,1):
147 if move not in board.legal_moves:raise ValueError('illegal played move')
148 row=by_ply.get(ply)
149 if row:
150 if row['uci']!=move.uci():raise ValueError('move report mismatch')
151 if board.turn==color and row.get('decision_source') not in ('model_policy','forced_mate_override'):raise ValueError('missing model attribution')
152 if board.turn!=color and ('model_query' in row or 'decision_source' in row or MODEL_METRICS.intersection(row)):raise ValueError('engine attributed to model')
153 if not math.isfinite(row['seconds']) or row['seconds']<0:raise ValueError('invalid move latency')
154 if board.turn==color:
155 model_turn_seconds+=row['seconds']
156 search=row.get('mate_search',{})
157 if search.get('max_plies')!=7 or search.get('node_budget')!=50000 or search.get('time_budget_seconds',1)>.25:raise ValueError('helper budget mismatch')
158 if search.get('status') not in ('proven','unknown','no_forced_mate'):raise ValueError('helper status missing')
159 if not math.isfinite(search.get('seconds',float('nan'))) or search['seconds']<0:raise ValueError('helper timing')
160 searches.append({k:search.get(k) for k in ('status','reason','seconds','completed_depth_plies','iteration_depths','workers','nodes','proof_verified')})
161 if row.get('decision_source')=='model_policy':
162 model_metrics(row,board)
163 queried.append(row)
164 if row.get('decision_source')=='forced_mate_override':
165 if board.turn!=color or row.get('model_query')!='not_queried' or MODEL_METRICS.intersection(row):raise ValueError('helper/model attribution mismatch')
166 search=row.get('mate_search',{});proof=search.get('proof',{});branches=proof.get('branches',[])
167 if search.get('status')!='proven' or search.get('move')!=move.uci():raise ValueError('helper move/status mismatch')
168 if not isinstance(branches,list) or len(branches)!=1 or branches[0].get('move')!=move.uci():raise ValueError('helper proof root differs from played move')
169 proof_check(h,board,proof,color);overrides+=1
170 board.push(move)
171 if board.fen()!=report['final_fen'] or game.headers['Result']!=report['result']:raise ValueError('final board/result mismatch')
172 outcome=board.outcome(claim_draw=True)
173 if report['result']!='*' and (outcome is None or outcome.result()!=report['result']):raise ValueError('fabricated scored result')
174 nodes=[];path=folder/'uci.log'
175 if path.exists():
176 for block in path.read_text().split('> go nodes 1000')[1:]:
177 observed=re.findall(r' nodes (\d+)',block);nodes.append(int(observed[-1]) if observed else None)
178 game.headers.update(OpeningID=opening['opening_id'],AutoplayPlies=str(n),SourceOpeningName=opening['name'])
179 node=game
180 for _ in range(n):node=node.variation(0);node.comment='Book autoplay; excluded from model metrics.'
181 return game,{'plies':len(moves),'autoplay_plies':n,'model_queries':len(queried),
182 'raw_greedy_legal':sum(r['raw_greedy_legal'] for r in queried),'raw_legal_probability_sum':sum(r['legal_joint_probability'] for r in queried),
183 'helper_overrides':overrides,'helper_searches':searches,'sunfish_reported_nodes':nodes,'result':report['result'],
184 'model_turn_seconds':model_turn_seconds,'latency_protocol':'model turns include helper attempt and decode; excludes book autoplay and model loading',
185 'termination':report['termination'],'error':report['error'],'cleanup_error':report['cleanup_error'],
186 'seconds':report['seconds'],'pgn_and_proofs_verified':True}
187
188def summarize(rows,total=100):
189 scored=[r for r in rows if r['result']!='*'];wins=draws=losses=0
190 for row in scored:
191 if row['result']=='1/2-1/2':draws+=1
192 elif row['result']==('1-0' if row['model_color']=='white' else '0-1'):wins+=1
193 else:losses+=1
194 paired={}
195 for row in rows:paired.setdefault(row['pair_id'],[]).append(row)
196 scores=[]
197 for pair in paired.values():
198 if len(pair)==2 and all(r['result']!='*' for r in pair):
199 scores.append(sum(.5 if r['result']=='1/2-1/2' else float(r['result']==('1-0' if r['model_color']=='white' else '0-1')) for r in pair)/2)
200 import statistics
201 return {'scheduled_games':total,'audited_games':len(rows),'unattempted_or_unaudited':total-len(rows),
202 'wins':wins,'draws':draws,'losses':losses,'unfinished':len(rows)-len(scored),
203 'score_on_scored_games':(wins+.5*draws)/len(scored) if scored else None,
204 'fully_scored_pairs':len(scores),'pair_mean_score':statistics.mean(scores) if scores else None,
205 'pair_standard_error':statistics.stdev(scores)/math.sqrt(len(scores)) if len(scores)>1 else None,
206 'uncertainty_limit':'paired-opening standard error; small selected suite, not an Elo/generalization estimate',
207 'model_queries':sum(r['model_queries'] for r in rows),'helper_overrides':sum(r['helper_overrides'] for r in rows),
208 'autoplay_excluded_from_model_metrics':True}
209
210def play(suite,out,checkpoint,h,clock,model_factory=None):
211 """Dependency-injected for offline scheduler/audit/cleanup tests."""
212 p=suite['protocol'];openings={o['opening_id']:o for o in suite['openings']};rows=[];games=[]
213 factory=model_factory or h.ModelWorker
214 write(out/'summary.json',summarize(rows,len(suite['schedule'])))
215 for item in suite['schedule']:
216 if clock.soft_stop():break
217 opening=openings[item['opening_id']];folder=out/item['game_id'];model=None
218 try:
219 timeout=min(p['model_timeout_seconds'],clock.remaining()-5)
220 if timeout<=0:break
221 load_started=time.monotonic();model=factory('adapter:load',checkpoint,item['seed'],timeout)
222 load_seconds=time.monotonic()-load_started
223 remaining=clock.remaining()-5
224 if remaining<=0:break
225 game_budget=min(p['game_walltime_seconds'],remaining)
226 game_end=time.monotonic()+game_budget
227 def engine():
228 available=min(clock.remaining()-5,game_end-time.monotonic())
229 if available<=0:raise TimeoutError('no time for engine initialization')
230 # UCI constructor performs two handshakes before the first search.
231 timeout=min(p['engine_timeout_seconds'],available/2)
232 command=[sys.executable,str(Path(__file__).resolve()),'--engine-child',str(os.getpid()),*h.engine_command()]
233 return h.UCI(command,timeout)
234 report=h.game(model,engine,item['model_color']=='white',folder,
235 cap=p['ply_cap_including_autoplay'],nodes=p['sunfish_requested_nodes'],opening=opening['uci'],
236 walltime=game_budget,label=f'Frozen paired{len(suite["schedule"])}; no Elo claim',
237 mate_override=True,mate_nodes=p['helper_nodes'],mate_seconds=p['helper_seconds'])
238 game,row=audit(h,folder,report,opening,item['model_color']=='white')
239 row.update(item);row['model_load_seconds']=load_seconds;rows.append(row);games.append(str(game))
240 write(folder/'game.pgn',str(game)+'\n')
241 row['pgn_sha256']=sha(folder/'game.pgn');row['game_json_sha256']=sha(folder/'game.json')
242 write(folder/'audit.json',row)
243 write(out/'results.json',rows);write(out/'summary.json',summarize(rows,len(suite['schedule'])))
244 write(out/'games.pgn','\n\n'.join(games)+'\n')
245 if report['cleanup_error'] or report['error']:break # No hidden retry/new budget.
246 finally:
247 if model is not None:model.close()
248 write(out/'summary.json',summarize(rows,len(suite['schedule'])))
249 return rows
250
251def compare(baseline,candidate,baseline_rows,candidate_rows,suite):
252 """Paired comparison only after checking identical evaluation conditions."""
253 import statistics
254 if baseline['request']['role']!='baseline' or candidate['request']['role']!='candidate':raise ValueError('comparison roles mismatch')
255 keys=('suite_sha256','execution_contract_sha256','runner_sha256','guardian_sha256','device','budget_seconds')
256 if any(baseline['request'][k]!=candidate['request'][k] for k in keys):raise ValueError('matched execution identity differs')
257 if any(baseline[k]!=candidate[k] for k in ('protocol','model_config','python','torch','transformers','python_chess')):raise ValueError('matched protocol/runtime differs')
258 if baseline['request']['suite_sha256']!=inputs()[1]['suite_sha256']:raise ValueError('comparison uses another suite')
259 if baseline['request']['checkpoint_sha256']!=suite['protocol']['baseline_checkpoint_sha256']:raise ValueError('wrong comparison baseline')
260 schedule={g['game_id']:g for g in suite['schedule']}
261 mapped=[]
262 for rows in (baseline_rows,candidate_rows):
263 table={r['game_id']:r for r in rows}
264 if len(table)!=len(rows) or set(table)!=set(schedule):raise ValueError('comparison requires all100 scheduled audits')
265 for key,row in table.items():
266 if any(row[k]!=schedule[key][k] for k in ('opening_id','model_color','seed','pair_id')) or row.get('pgn_and_proofs_verified') is not True:raise ValueError('comparison schedule/audit mismatch')
267 mapped.append(table)
268 complete=all(r['result']!='*' and not r['error'] and not r['cleanup_error'] for rows in mapped for r in rows.values())
269 result={'identical_protocol_verified':True,'all_games_scored_without_errors':complete,
270 'baseline':summarize(baseline_rows),'candidate':summarize(candidate_rows),'promotion_authorized':False}
271 if not complete:
272 return dict(result,comparison_status='incomplete; no improvement conclusion',evidence_for_improvement=False)
273 def score(row):return .5 if row['result']=='1/2-1/2' else float(row['result']==('1-0' if row['model_color']=='white' else '0-1'))
274 differences=[]
275 for opening in suite['openings']:
276 ids=[g['game_id'] for g in suite['schedule'] if g['opening_id']==opening['opening_id']]
277 differences.append(sum(score(mapped[1][key])-score(mapped[0][key]) for key in ids)/2)
278 mean=statistics.mean(differences);se=statistics.stdev(differences)/math.sqrt(len(differences))
279 interval=[mean-1.96*se,mean+1.96*se]
280 return dict(result,comparison_status='matched',candidate_minus_baseline_score=mean,
281 opening_pair_standard_error=se,approximate_95_percent_interval=interval,
282 evidence_for_improvement=interval[0]>0,
283 uncertainty_limit='normal approximation over50 opening pairs; selected suite, not an Elo estimate; independent review required')
284
285def compare_directories(baseline_path,candidate_path):
286 suite,contract=inputs();verify_sources(contract)
287 import harness as h
288 openings={o['opening_id']:o for o in suite['openings']};manifests=[];results=[]
289 for root in map(Path,(baseline_path,candidate_path)):
290 manifest=json.loads((root/'manifest.json').read_text());manifests.append(manifest)
291 expected={'execution_contract_sha256':sha(ROOT/'execution-contract.json'),'runner_sha256':sha(__file__),
292 'guardian_sha256':sha(GUARDIAN_PATH),'suite_sha256':contract['suite_sha256']}
293 if any(manifest['request'][k]!=v for k,v in expected.items()) or manifest['protocol']!=suite['protocol']:raise ValueError('comparison source contract changed')
294 rows=json.loads((root/'results.json').read_text())
295 for row in rows:
296 folder=(root/row['game_id']).resolve()
297 if folder.parent!=root.resolve():raise ValueError('unsafe game artifact path')
298 if sha(folder/'game.pgn')!=row['pgn_sha256'] or sha(folder/'game.json')!=row['game_json_sha256']:raise ValueError('played artifacts changed')
299 report=json.loads((folder/'game.json').read_text())
300 _,checked=audit(h,folder,report,openings[row['opening_id']],row['model_color']=='white')
301 if any(row[key]!=checked[key] for key in ('result','termination','error','cleanup_error','plies','autoplay_plies','model_queries','helper_overrides','raw_greedy_legal','raw_legal_probability_sum')):
302 raise ValueError('stored result differs from replayed game audit')
303 results.append(rows)
304 return compare(*manifests,*results,suite)
305
306def worker(request_path):
307 # The private entry point must not bypass the external hard watchdog.
308 require_guardian()
309 request=json.loads(Path(request_path).read_text());out=Path(request_path).parent
310 guardian=load_guardian(request.get('guardian_sha256'))
311 value=guardian.read_deadline(out/'deadline.json')
312 expected_budget=600 if json.loads((ROOT/'execution-contract.json').read_text()).get('diagnostic_subset') is not None else 7200
313 if (set(request)!=APPROVAL_KEYS or value['identity']!=request or request.get('approved') is not True
314 or request['budget_seconds']!=expected_budget or value['budget_seconds']!=expected_budget or value['checkpoint_margin_seconds']!=30):raise ValueError('worker request/deadline mismatch')
315 if str(uuid.UUID(request['run_id']))!=request['run_id']:raise ValueError('invalid worker run UUID')
316 if out.resolve()!=(ROOT/'runs'/request['run_id']).resolve() or str(out.resolve())!=request['run_directory']:raise ValueError('noncanonical worker run directory')
317 clock=guardian.Deadline(value)
318 if clock.soft_stop():raise TimeoutError('evaluation budget expired before setup')
319 suite,contract=inputs();verify_sources(contract)
320 if request['suite_sha256']!=contract['suite_sha256'] or request['runner_sha256']!=sha(__file__) or request['execution_contract_sha256']!=sha(ROOT/'execution-contract.json') or request['guardian_sha256']!=sha(GUARDIAN_PATH):
321 raise ValueError('worker approved source changed')
322 if request['device'] not in ('cuda:0','cuda:1') or request['role'] not in ('baseline','candidate'):raise ValueError('invalid worker role/device')
323 if request['role']=='baseline' and request['checkpoint_sha256']!=suite['protocol']['baseline_checkpoint_sha256']:raise ValueError('wrong worker baseline')
324 if sha(request['checkpoint'])!=request['checkpoint_sha256'] or sha(request['dataset_manifest'])!=request['dataset_manifest_sha256']:raise ValueError('checkpoint/dataset changed')
325 # Single attempt even when the private worker entry point is invoked twice.
326 with (out/'worker-started.json').open('x') as marker:
327 json.dump({'pid':os.getpid(),'started_unix':time.time(),'request_sha256':sha(request_path)},marker);marker.flush();os.fsync(marker.fileno())
328 import torch,transformers,chess
329 saved=torch.load(request['checkpoint'],map_location='cpu',weights_only=True)
330 cfg=saved['model_config']
331 from checkpoint_gate import permitted,validate_milestone
332 from adapter import validate_identity
333 stage,ref=permitted(contract);validate_identity(saved,stage);validate_milestone(saved,contract)
334 if ref!={'path':request['checkpoint'],'sha256':request['checkpoint_sha256']} or cfg['vocab_size']!=512:raise ValueError('wrong certified state checkpoint')
335 if saved['identity']['sealed_dataset_manifest_sha256']!=request['dataset_manifest_sha256']:raise ValueError('checkpoint dataset mismatch')
336 write(out/'manifest.json',{'request':request,'protocol':suite['protocol'],'model_config':cfg,
337 'checkpoint_identity':saved['identity'],'checkpoint_cursor':saved['exposures']['cursor'],'checkpoint_updates':saved['updates'],
338 'python':sys.version,'torch':str(torch.__version__),'transformers':transformers.__version__,
339 'python_chess':chess.__version__,'model_reload_each_game':True,'test_set_evaluated':False})
340 del saved
341 import harness as h
342 os.environ['CHESS_INFERENCE_DEVICE']=request['device']
343 try:
344 # Same enforceable model-worker deadline as matches, before any game.
345 preflight=h.ModelWorker('adapter:load',Path(request['checkpoint']),20261029,min(60.,clock.remaining()-5))
346 try:
347 board=chess.Board();move,metrics=preflight.choose(board)
348 if move not in board.legal_moves:raise ValueError('preflight illegal move')
349 model_metrics(dict(metrics,model_query='queried'),board)
350 write(out/'preflight.json',{'legal_move':move.uci(),'metrics':metrics,'checkpoint_sha256':request['checkpoint_sha256'],'unix':time.time()})
351 finally:preflight.close()
352 rows=play(suite,out,Path(request['checkpoint']),h,clock)
353 write(out/'terminal.json',{'status':'all_scheduled_audited' if len(rows)==len(suite['schedule']) else 'partial','audited_games':len(rows),'test_set_evaluated':False})
354 except BaseException as error:
355 write(out/'failure.json',{'error':repr(error)});raise
356
357def launch(approval_path):
358 import fcntl
359 suite,contract=inputs();approval=json.loads(Path(approval_path).read_text());run_id=approval.get('run_id')
360 expected_budget=600 if contract.get('diagnostic_subset') is not None else 7200
361 if str(uuid.UUID(run_id))!=run_id:raise ValueError('canonical run UUID required')
362 if set(approval)!=APPROVAL_KEYS or approval['approved'] is not True or approval['budget_seconds']!=expected_budget:raise ValueError('exact reviewed match approval required')
363 if approval['suite_sha256']!=contract['suite_sha256'] or approval['execution_contract_sha256']!=sha(ROOT/'execution-contract.json') or approval['runner_sha256']!=sha(__file__):raise ValueError('approved source/suite mismatch')
364 guardian=load_guardian(approval['guardian_sha256'])
365 if approval['device'] not in ('cuda:0','cuda:1') or approval['role'] not in ('baseline','candidate'):raise ValueError('invalid reviewed device/role')
366 if approval['role']=='baseline' and approval['checkpoint_sha256']!=suite['protocol']['baseline_checkpoint_sha256']:raise ValueError('incorrect baseline checkpoint')
367 for key in ('checkpoint','dataset_manifest'):
368 if str(Path(approval[key]).resolve())!=approval[key] or not Path(approval[key]).is_file():raise ValueError('canonical existing input required')
369 out=(ROOT/'runs'/run_id).resolve();out.parent.mkdir(exist_ok=True)
370 if approval['run_directory']!=str(out):raise ValueError('alternate run directory forbidden')
371 # Fresh UUID directory only; no replay/resume/reset of an earlier match budget.
372 out.mkdir(exist_ok=False)
373 with (out/'owner.lock').open('x') as lock:
374 fcntl.flock(lock,fcntl.LOCK_EX|fcntl.LOCK_NB)
375 value=guardian.create_or_resume(out/'deadline.json',approval,budget=expected_budget,margin=30)
376 write(out/'request.json',approval)
377 env=dict(os.environ,CHESS_JOB_LOCK_FD=str(lock.fileno()),CHESS_MATCH_GUARDED='1')
378 command=[sys.executable,str(Path(__file__).resolve()),'--worker',str(out/'request.json')]
379 result=guardian.supervise(command,value,env);write(out/'supervision.json',result)
380 return result
381
382def main():
383 if sys.argv[1:2]==['--engine-child']:
384 return engine_child(int(sys.argv[2]),sys.argv[3:])
385 if sys.argv[1:2]==['--worker']:
386 path=Path(sys.argv[2]).resolve()
387 if path.name!='request.json' or path.parent.parent!=(ROOT/'runs').resolve():raise ValueError('private worker path outside run registry')
388 with (path.parent/'worker.log').open('a',buffering=1) as log:
389 os.dup2(log.fileno(),1);os.dup2(log.fileno(),2)
390 return worker(path)
391 parser=argparse.ArgumentParser();parser.add_argument('--approval');parser.add_argument('--authorize-matches',action='store_true')
392 parser.add_argument('--compare',nargs=2,metavar=('BASELINE','CANDIDATE'))
393 args=parser.parse_args()
394 if args.compare:
395 if args.authorize_matches or args.approval:parser.error('comparison is read-only and cannot launch')
396 print(json.dumps(compare_directories(*args.compare),indent=2));return
397 if not args.authorize_matches:
398 suite,contract=inputs();print(json.dumps({'status':'plan_only','games_per_checkpoint':len(suite['schedule']),'suite_sha256':contract['suite_sha256'],'runner_sha256':sha(__file__),'matches_run':0}));return
399 if not args.approval:parser.error('reviewed approval file required')
400 result=launch(args.approval)
401 if result['returncode'] or result['deadline_expired']:raise SystemExit(result['returncode'] or 124)
402if __name__=='__main__':main()
403