from pathlib import Path import json,hashlib,subprocess R=Path('/home/jakub/devel/escapistsrereintroduced');B=Path('/tmp/erri-bmp-native-2103') def sha(p): h=hashlib.sha256() with p.open('rb') as f: while chunk:=f.read(1024*1024):h.update(chunk) return h.hexdigest() def verify(root,manifest,exact=False): data=json.loads(manifest.read_text()); missing=[];changed=[] for n,h in data.items(): p=root/n if not p.is_file():missing.append(n) elif sha(p)!=h:changed.append(n) actual={str(p.relative_to(root)) for p in root.rglob('*') if p.is_file()} if exact else set(data) return {'missing':missing,'changed':changed,'count':len(data),'unexpected':sorted(actual-set(data)),'manifest_sha256':sha(manifest)} original=verify(Path('/home/jakub/devel/escapists'),Path('/tmp/erri-heartbeat-20260930-1542-reference.json')) candidates={n:verify(R/'.build'/('playtest-2026-10-03-'+n),R/'docs/evidence'/('playtest-refresh-2026-10-03-'+n)/'candidate-sha256.json',True) for n in ['crash-start','depot-mines','ground-supply','mine-safety','mounted-pair']} staged=hashlib.sha256(subprocess.check_output(['git','diff','--cached','--binary'],cwd=R)).hexdigest() baseline=json.loads((B/'baseline.json').read_text()) assert staged==baseline['staged_diff_sha256'] for result in [original,*candidates.values()]:assert not result['missing'] and not result['changed'] and not result['unexpected'],result (B/'preservation.json').write_text(json.dumps({'complete':True,'original':original,'candidates':candidates,'staged_diff_sha256':staged},indent=2)+'\n') print('Original533, five sealed candidates and staged diff unchanged')