from pathlib import Path import sys,json,hashlib,shutil,subprocess R=Path('/home/jakub/devel/escapistsrereintroduced');B=Path('/tmp/erri-gameplay-1130');F=R/'.build/recovery-launcher-native-1130';E=R/'docs/evidence/recovery-launcher-2026-10-02';sys.path.insert(0,str(R/'tools')) from source_manifest import addon_manifest sha=lambda p:hashlib.sha256(p.read_bytes()).hexdigest() def write(p,v):p.write_text(json.dumps(v,indent=2)+'\n') before=json.loads((B/'baseline.json').read_text());current=addon_manifest(R) assert current==json.loads((F/'frozen-source.json').read_text()) suite=json.loads((B/'suite-result.json').read_text());assert suite['exit']==0 and suite['inputs_unchanged'] and suite['regression_programs']==283 bindings=json.loads((B/'suite-inputs.json').read_text());assert all(sha(R/n)==h for n,h in bindings.items()) assert hashlib.sha256(subprocess.check_output(['git','diff','--cached','--binary'],cwd=R)).hexdigest()==json.loads((B/'index-before-sha256.json').read_text())['sha256'] obs=Path('/tmp/erri-observer-recovery-warning');launcher=Path('/tmp/erri-launcher-resupply-1140');reviewer=Path('/tmp/erri-launcher-review-1130') om=json.loads((obs/'source-manifest.json').read_text());lm=json.loads((launcher/'source-manifest.json').read_text());allowed=set(om)|set(lm) assert all(sha(R/n)==v['proposal_sha256'] for n,v in om.items()) assert all(sha(R/n)==h for n,h in lm.items()) lr=json.loads((reviewer/'review.json').read_text());assert lr['decision'].startswith('FINAL APPROVAL') and all(sha(R/n)==h for n,h in lr['source_sha256'].items()) assert set(current)==set(before['authored']) changed=[n for n,h in before['authored'].items() if current[n]!=h];assert len(changed)==6 and set(changed)<=allowed assert all((sha(R/n) if (R/n).is_file() else None)==h for n,h in before['unstaged'].items() if n not in allowed) original=json.loads(Path('/tmp/erri-heartbeat-20260930-1542-reference.json').read_text());assert all(sha(Path('/home/jakub/devel/escapists')/n)==h for n,h in original.items()) package=R/'.build/playtest-2026-10-02-objective-map';pm=json.loads((R/'docs/evidence/playtest-refresh-2026-10-02-objective-map/candidate-sha256.json').read_text());assert {str(p.relative_to(package)):sha(p) for p in package.rglob('*') if p.is_file()}==pm name='native-2026-10-02-recovery-launcher-normal';source=F/'docs/evidence'/name report=json.loads((source/'report.json').read_text());runner=json.loads((source/'runner.json.txt').read_text()) assert report['smoke_completions']==1 and report['assertions_passed']==63 and not report['script_or_runtime_failures'] and len(report['engine_errors'])==13 assert runner['cleanup_confirmed'] and runner['source_unchanged_after_run'] and runner['external_addons_unchanged_after_run'] E.mkdir();shutil.copytree(source,R/'docs/evidence'/name) for p in B.iterdir(): if p.is_file() and p.suffix in {'.json','.log','.py'}:shutil.copyfile(p,E/p.name) for folder,label in [(obs,'observer'),(launcher,'launcher'),(reviewer,'independent-launcher')]: out=E/label;out.mkdir() for p in folder.iterdir(): if p.is_file() and p.suffix in {'.json','.log','.patch','.txt','.c','.py'}:shutil.copyfile(p,out/p.name) shutil.copyfile('/tmp/erri-hq-road-proposal-1130/proposal.json',E/'next-motorized-interception-proposal.json') write(E/'source-after.json',current) summary={'implemented':['Observer hints append current replicated recovery/defeat status, retry unaccepted delivery and clear on wake/end/ownership loss.','Delivered supported empty-launcher demand can reserve original infantry/truck and transfer compatible finite stock after existing rifle/mounted work. No new stock or disposable reload.'], 'authored_files':len(current),'changed_authored_files':changed,'registered_regression_programs_passed':283,'observer_native':{'assertions':29,'completions':1,'script_failures':0,'engine_errors':13,'source_scope':'Observer/probe exactly current; four AI files subsequently changed for launcher support.'},'normal_native':{'assertions':63,'completions':1,'script_failures':0,'engine_errors':13,'source_scope':'Exact final 407 authored files.'},'native_qualification':'failed; retained engine errors','launcher_physical_transfer_proven':False,'multiplayer_proven':False,'fps_improvement_proven':False,'package_refreshed':False,'existing_candidate_files_unchanged':len(pm),'original_reference_files_unchanged':len(original),'inherited_unstaged_paths':len(before['unstaged']),'inherited_overlap_paths':sorted(set(before['unstaged'])&allowed),'other_inherited_edits_unchanged':True,'cached_diff_unchanged':True,'committed':False,'published':False,'next_proposal':'Motorized interception from delivered travel history is design only; current authorization covers future hidden/muted validation, without a new user permission gate.'} write(E/'review.json',summary) print(json.dumps(summary,indent=2))