Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
74 lines
6.8 KiB
Python
74 lines
6.8 KiB
Python
"""Root-only final evidence sealing after reviewed documentation application; no engine launch."""
|
|
from pathlib import Path
|
|
import hashlib,json,shutil,subprocess,sys
|
|
R=Path('/home/jakub/devel/escapistsrereintroduced')
|
|
B=Path('/tmp/erri-gameplay-root-1305'); OLD=Path('/tmp/erri-gameplay-root-1210')
|
|
E=R/'docs/evidence/playtest-refresh-2026-10-03-depot-mines'
|
|
C=R/'.build/playtest-2026-10-03-depot-mines';F=R/'.build/playtest-source-2026-10-03-depot-mines'
|
|
D=Path('/tmp/erri-playtest-review-1305');REUSE=Path('/tmp/erri-playtest-review-1210');P=Path('/tmp/erri-package-prep-1305')
|
|
FAIL=R/'docs/evidence/package-failure-2026-10-03-depot-mines'
|
|
sha=lambda p:hashlib.sha256(p.read_bytes()).hexdigest();load=lambda p:json.loads(p.read_text())
|
|
def write(p,v):p.write_text(json.dumps(v,indent=2)+'\n')
|
|
def tree(p):return {str(q.relative_to(p)):sha(q) for q in sorted(p.rglob('*')) if q.is_file()}
|
|
base=load(OLD/'baseline.json');changed=[p for p,h in base['files'].items() if not (R/p).is_file() or sha(R/p)!=h]
|
|
ours={'README.md','docs/current-status.md','docs/playtest-build.md'}
|
|
concurrent={'addons/core/Scripts/Game/ERR/00_Core/ERR_WelcomeVoice.c','tools/check.py'}
|
|
# Intentionally refuses any new baseline modification, including BMP implementation:
|
|
# seal this tested candidate before those separately reviewed edits are integrated.
|
|
assert set(changed)<=ours|concurrent and ours<=set(changed),changed
|
|
assert hashlib.sha256(subprocess.check_output(['git','diff','--cached','--binary'],cwd=R)).hexdigest()==base['index_diff_sha256']
|
|
original=load(Path('/tmp/erri-heartbeat-20260930-1542-reference.json'))
|
|
assert all(sha(Path('/home/jakub/devel/escapists')/p)==h for p,h in original.items())
|
|
prior=[]
|
|
for name in ['ground-supply','mine-safety','mounted-pair']:
|
|
old=R/('.build/playtest-2026-10-03-'+name)
|
|
seal=load(R/('docs/evidence/playtest-refresh-2026-10-03-'+name+'/candidate-sha256.json'))
|
|
assert tree(old)==seal;prior.append({'name':name,'files_unchanged':len(seal)})
|
|
review=load(D/'final-review.json');assert review['complete'] is True
|
|
assert sha(D/'final-review.json')==(B/'approved-review-sha256.txt').read_text().strip()
|
|
assert load(P/'docs-proposal.json')['target_writes'] is True
|
|
assert all(sha(Path(n))==h for n,h in load(P/'docs-after.json').items())
|
|
sys.path.insert(0,str(F/'tools'));from source_manifest import addon_manifest
|
|
frozen=load(F/'frozen-source.json');assert len(frozen)==423 and addon_manifest(F)==frozen==load(OLD/'frozen-source.json')
|
|
live=addon_manifest(R);assert all(live.get(n)==h for n,h in frozen.items())
|
|
assert set(live)-set(frozen)=={'addons/core/Scripts/Game/ERR/00_Core/ERR_WelcomeVoice.c'}
|
|
h=load(C/'handoff.json')
|
|
assert h['normal_mission_ready'] and h['local_participant_verified'] and h['repository_regression_programs']==301 and not h['release_qualified']
|
|
assert h['authored_files']==423 and h['pak_payload_files']==364 and len(h['runtime_files'])==3
|
|
failed=load(FAIL/'artifact-manifest.json')
|
|
assert failed['reported_result']=='timeout' and failed['native_exit_code'] is None and failed['candidate_created'] is False
|
|
assert all(sha(FAIL/n)==v['sha256'] for n,v in failed['files'].items())
|
|
assert set(tree(FAIL))==set(failed['files'])|{'artifact-manifest.json'}
|
|
relocation=load(FAIL/'scratch-relocation.json')
|
|
assert Path(relocation['source']).is_symlink() and Path(relocation['source']).resolve()==Path(relocation['destination'])
|
|
assert sha(Path(relocation['destination']))==relocation['sha256']
|
|
failed_seal=tree(FAIL)
|
|
E.mkdir(exist_ok=False)
|
|
for n in ['baseline.json','frozen-source.json','freeze.py','source-bundle.log','excluded-live-additions.json','package-preflight-refusal.log']:
|
|
shutil.copyfile(OLD/n,E/n)
|
|
shutil.copyfile(__file__,E/'finish-evidence.py')
|
|
shutil.copyfile(B/'package.log',E/'package-1305.log')
|
|
for n in ['full-suite.log','suite-inputs.json','suite-result.json']:
|
|
shutil.copyfile(Path('/tmp/erri-depot-mines-root-1116')/n,E/n)
|
|
shutil.copyfile(D/'final-review.json',E/'independent-review.json')
|
|
shutil.copyfile(REUSE/'preflight.json',E/'suite-reuse-review.json')
|
|
shutil.copyfile(REUSE/'docs-review.json',E/'post-suite-docs-review.json')
|
|
shutil.copytree(P,E/'preparation',ignore=shutil.ignore_patterns('__pycache__','*.pyc'))
|
|
shutil.copytree(FAIL,E/'failed-package-1210')
|
|
assert tree(E/'failed-package-1210')==failed_seal==tree(FAIL)
|
|
seal=tree(C);write(E/'candidate-sha256.json',seal)
|
|
concurrent_state={n:{'before':base['files'].get(n),'observed_after':sha(R/n)} for n in set(changed)&concurrent}
|
|
write(E/'review.json',{
|
|
'kind':'UNQUALIFIED DEVELOPMENT CANDIDATE','candidate':str(C),'authored_files':423,'pak_payload_files':364,'runtime_files':3,'candidate_files':len(seal),'source_zip_sha256':sha(C/'source.zip'),
|
|
'regression_programs':301,'fresh_full_suite_run':False,'suite_reused_for_exact_frozen_source_tests_tools':True,'three_post_suite_prose_changes_independently_reviewed':True,
|
|
'normal_route_reused_for_exact_source':True,'normal_assertions':64,'normal_completions':1,'normal_script_failures':0,'normal_engine_errors':13,'native_initial_camp_stock':{'camps':5,'inert_original_mines':10},
|
|
'normal_random_radius_trace_enabled':True,'normal_random_radius_reproduction_or_trace':False,'packed_normal_mission_and_local_prisoner':True,'packed_script_failures':0,'packed_engine_errors':17,
|
|
'strict_failures_retained':True,'release_qualified':False,'published':False,'snapshot_source_is_unchanged_subset_of_live_source_at_seal':True,'live_source_equivalence_claimed':False,
|
|
'excluded_concurrent_work':load(OLD/'excluded-live-additions.json'),'observed_concurrent_baseline_changes':concurrent_state,'original_reference_files_unchanged':len(original),'existing_paths_unchanged':len(base['files'])-len(changed),
|
|
'our_documentation_updates':sorted(ours),'index_diff_sha256':base['index_diff_sha256'],'previous_candidates':prior,'independent_review_sha256':sha(E/'independent-review.json'),
|
|
'prior_failed_package':{'archive':str(FAIL),'archive_manifest_sha256':sha(FAIL/'artifact-manifest.json'),'files_preserved':len(failed_seal),'result':'timeout','native_exit_code':None,'candidate_created':False,'quota_failure_retained':True},
|
|
'quota_relief':relocation,
|
|
'scope':'Exact tested finite camp-mine courier and compatible original porter snapshot. Concurrent welcome-voice work and later source/test changes, including BMP sampler corrections, are excluded from this handoff. Sealing precedes BMP integration; no broad preservation exceptions. Autonomous mine/resupply/interception, human escape, multiplayer, manual UI, FPS and clean release remain unqualified. Intermittent zero-radius error remains unresolved.'})
|
|
write(E/'evidence-sha256.json',{str(p.relative_to(E)):sha(p) for p in sorted(E.rglob('*')) if p.is_file() and p.name!='evidence-sha256.json'})
|
|
print(json.dumps({'candidate':str(C),'files':len(seal),'source_zip_sha256':sha(C/'source.zip'),'original_preserved':len(original),'previous_candidates_preserved':prior,'failed1210_archive_preserved':len(failed_seal),'concurrent_changes_preserved':sorted(concurrent_state)},indent=2))
|