from pathlib import Path import hashlib,json,shutil,subprocess,sys r=Path('/home/jakub/devel/escapistsrereintroduced');b=Path('/tmp/erri-playtest-menu-fix-1349');p=Path('/tmp/erri-playtest-menu-fix-docs-1349');build=r/'.build/playtest-2026-10-02-hq-memory-menu-fix';e=r/'docs/evidence/playtest-refresh-2026-10-02-hq-memory-menu-fix' sha=lambda p:hashlib.sha256(p.read_bytes()).hexdigest() read=lambda p:json.loads(p.read_text()) write=lambda p,v:p.write_text(json.dumps(v,indent=2)+'\n') sys.path.insert(0,str(r/'tools'));from source_manifest import addon_manifest baseline=read(b/'baseline.json');proposal=read(p/'proposal.json');assert proposal['mode']=='verified-final-proposal' bindings=read(p/'validation-bindings.json');source=Path(bindings['source_root']);testroot=Path(bindings['suite_root']);live=read(Path(bindings['live_preservation'])) assert addon_manifest(source)==baseline['source'] assert addon_manifest(r)==live['source'] assert all(sha(r/n)==h for n,h in live['working_modified'].items()) assert hashlib.sha256(subprocess.check_output(['git','diff','--cached','--binary'],cwd=r)).hexdigest()==baseline['index_diff_sha256'] original=read(Path('/tmp/erri-heartbeat-20260930-1542-reference.json')) prior=read(r/'docs/evidence/playtest-refresh-2026-10-02-objective-map/candidate-sha256.json') assert all(sha(Path('/home/jakub/devel/escapists')/n)==h for n,h in original.items()) assert {str(x.relative_to(r/'.build/playtest-2026-10-02-objective-map')):sha(x) for x in (r/'.build/playtest-2026-10-02-objective-map').rglob('*') if x.is_file()}==prior failedroot=r/'.build/playtest-2026-10-02-hq-memory' failedmanifest=read(p/'failed-candidate-sha256.json') assert len(failedmanifest)==418 and {str(x.relative_to(failedroot)):sha(x) for x in failedroot.rglob('*') if x.is_file()}==failedmanifest oldbaseline=read(Path('/tmp/erri-playtest-1349/baseline.json')) fixpaths={'addons/core/Scripts/Game/ERR/00_Core/ERR_TerrainTakeover.c','tests/test_terrain_takeover.py'} assert {n for n,h in oldbaseline['source'].items() if baseline['source'][n]!=h}=={'addons/core/Scripts/Game/ERR/00_Core/ERR_TerrainTakeover.c'} assert all(h==baseline['working_modified'][n] for n,h in oldbaseline['working_modified'].items() if n not in fixpaths) assert len(baseline['working_modified'])==97 h=read(build/'handoff.json');assert h['authored_files']==409 and h['pak_payload_files']==351 and len(h['runtime_files'])==3 assert h['normal_mission_ready'] and h['local_participant_verified'] and h['repository_regression_programs']==285 and not h['release_qualified'] and not h['strict_packed_consumption_verified'] for n,v in proposal['documentation_baselines'].items():assert sha(r/n)==v assert len(proposal['proposed_destinations'])==5 assert h['packed_script_failures']==0 and h['packed_resource_errors']==17 freshsuite=read(Path(bindings['suite_result']));assert freshsuite['exit']==0 and freshsuite['regression_programs']==285 and freshsuite['inputs_unchanged'] assert all(sha(testroot/n)==v for n,v in read(Path(bindings['suite_inputs'])).items()) assert addon_manifest(testroot)==baseline['source'] route=r/'docs/evidence/native-2026-10-02-hq-memory-menu-fix-normal' rr=read(route/'report.json');assert rr['assertions_passed']==63 and rr['smoke_completions']==1 and not rr['script_or_runtime_failures'] and len(rr['engine_errors'])==13 assert read(route/'source-sha256.json')==baseline['source'] assert Path('/tmp/erri-playtest-menu-fix-review-1349/review.json').exists(), 'Independent final package review pending' live_result=read(b/'suite-result.json');assert live_result['exit']==1 and not live_result['inputs_unchanged'] and live_result['regression_programs']==285 and all(row['exit']==0 for row in live_result['programs']) e.mkdir(exist_ok=False) concurrent=e/'concurrent-live-suite';concurrent.mkdir() for name in ['suite-result.json','suite-inputs.json','regressions.log']: shutil.copyfile(b/name,concurrent/name) shutil.copyfile(p/'failed-candidate-sha256.json',e/'failed-candidate-sha256.json') failed=e/'initial-failed-candidate';failed.mkdir() shutil.copyfile('/tmp/erri-playtest-review-1349/review.json',failed/'independent-review.json') oldrun=Path('/tmp/erri-packed-chat-20261002-hq-memory-final') for name in ['packed-startup-report.json','packed-runner.json','packed-input-provenance.json']: shutil.copyfile(oldrun/name,failed/name) oldreport=read(oldrun/'packed-startup-report.json');assert len(oldreport['script_or_runtime_failures'])==1 and len(oldreport['engine_errors'])==18 oldlogs=Path(read(oldrun/'packed-runner.json')['session']) for name in ['console.log','script.log','error.log']: if (oldlogs/name).exists():shutil.copyfile(oldlogs/name,failed/(name+'.txt')) fix=e/'menu-guard-fix';fix.mkdir() for name in ['fix.patch','baseline.json','review.json','red.log','green.log']: shutil.copyfile(Path('/tmp/erri-takeover-menu-fix-1349')/name,fix/name) for name in ['takeover-guard-review.json','takeover-red.log','takeover-green.log']: shutil.copyfile(Path('/tmp/erri-playtest-review-1349')/name,fix/('independent-'+name)) shutil.copyfile(b/'baseline.json',e/'baseline.json') shutil.copyfile(Path(bindings['suite_result']),e/'suite-result.json') shutil.copyfile(Path(bindings['suite_inputs']),e/'suite-inputs.json') shutil.copyfile(Path(bindings['live_preservation']),e/'concurrent-live-preservation.json') shutil.copyfile(p/'validation-bindings.json',e/'validation-bindings.json') shutil.copyfile('/tmp/erri-package-20261002-hq-memory.log',e/'initial-package-concurrency-refusal.log.txt') shutil.copyfile(b/'packed-concurrency-refusal.log',e/'packed-concurrency-refusal.log.txt') shutil.copyfile('/tmp/erri-playtest-1349/concurrent-work.json',e/'concurrent-work.json') shutil.copyfile('/tmp/erri-playtest-menu-fix-review-1349/review.json',e/'independent-package-review.json') shutil.copyfile(p/'prepare.py',e/'prepare-documentation.py');shutil.copyfile(p/'proposal.json',e/'documentation-proposal.json') for n,v in proposal['documentation_baselines'].items(): shutil.copyfile(r/n,e/(Path(n).name+'.before')) for n in proposal['proposed_destinations']: assert n in ['.build/playtest-2026-10-02-hq-memory-menu-fix/README.md',*proposal['documentation_baselines']] shutil.copyfile(p/'proposed'/n,r/n) summary={'artifact':str(build.relative_to(r)),'authored_files':409,'pak_payload_files':351,'runtime_files':3,'regression_programs':285,'fresh_suite_and_normal_route_match_packaged_source':True,'source_scope':'Sealed409 snapshot; newer concurrent live terrain-name/presentation work preserved but not packaged','included_changes':['Observer recovery/defeat guidance','Finite supported-launcher resupply','Radio-directed motorized interception from delivered travel history','Concurrent automatic terrain takeover work preserved, with mode-less menu preflight guard'],'native_normal_route':{'assertions':63,'rounds':1,'script_failures':0,'retained_engine_errors':13},'packed_ordinary_startup':{'normal_mission_ready':True,'local_prisoner_verified':True,'script_failures':0,'retained_engine_errors':17,'strict_failure_retained':True},'native_packaging':'Child exit0 and exact authored/payload identity; strict completion/prefix-active failure retained. Unqualified development candidate.','preserved':{'working_modified_paths_before_doc_updates':len(baseline['working_modified']),'captured_concurrent_working_paths':len(live['working_modified']),'original_reference_files':len(original),'previous_candidate_files':len(prior),'retained_failed_diagnostic_candidate_files':len(failedmanifest),'index_unchanged':True},'remaining':'Physical interception/holding/rejoin, physical launcher transfer, human escape, held-map rendering, real multiplayer/JIP/reconnect/twelve players, comparative FPS and clean release.','initial_failed_candidate':{'script_failures':1,'engine_errors':18,'bytes_preserved':True},'committed':False,'published':False,'release_qualified':False} write(e/'review.json',summary) write(e/'documentation-after.json',{n:sha(r/n) for n in proposal['proposed_destinations']}) write(e/'candidate-sha256.json',{str(x.relative_to(build)):sha(x) for x in sorted(build.rglob('*')) if x.is_file()}) shutil.copyfile(__file__,e/'finalize.py') for n,v in live['working_modified'].items(): if n not in proposal['documentation_baselines']:assert sha(r/n)==v,n assert {str(x.relative_to(failedroot)):sha(x) for x in failedroot.rglob('*') if x.is_file()}==failedmanifest assert addon_manifest(source)==baseline['source'] assert addon_manifest(r)==live['source'] assert hashlib.sha256(subprocess.check_output(['git','diff','--cached','--binary'],cwd=r)).hexdigest()==baseline['index_diff_sha256'] subprocess.run(['git','diff','--check'],cwd=r,check=True) print(json.dumps(summary,indent=2))