#!/usr/bin/env python3 """Read-only replay of immutable raw E incidents; never rewrite old verdicts.""" import json,re from pathlib import Path from PIL import Image import validators as v from saved_validators import held_configure,released_configure,rgb_exact,timeout_line from ipc_predicates import nodes,ancestry,workspace from gate import sha,LAB,durable HIST=Path('/home/fy59/swayfx-mosaic-minimal-core-2l7riqt_/graphics/runs') CORE='29baf31aa3eeed259825c87d0799fa5d3dc83710afb967154604eb1c6657f965' def saved_raw(): d=HIST/'E6/run';raw=(d/'owner.log').read_text();ev=[json.loads(l) for l in (d/'events.jsonl').read_text().splitlines()] release=next(e['ns'] for e in ev if e['kind']=='client-request' and e.get('command')=='release_configure') held_serial=int(re.search(r'HELD ns=\d+ serial=(\d+)',raw)[1]) cut=raw.index('COMMAND hold_next_configure DONE');before=raw[:cut];prior=int(re.findall(r'ACK ns=\d+ serial=(\d+)',before)[-1]) tail=raw[cut:];wire=re.search(rf'[^\n]*xdg_surface#\d+\.ack_configure\({held_serial}\)',tail) holdtext=tail[:wire.start()];held=held_configure(before,holdtext,prior) caps=[e for e in ev if e['kind']=='capture'];post=next(e for e in caps if e['tag']=='natural-timeout-H1')['start_ns'] live=released_configure(held,tail,release,post) request=next(e['ns'] for e in ev if e['kind']=='ipc-request' and e['args']==['gaps inner current set 30']) timeout=timeout_line((d/'compositor.log').read_text(),-1,True,request,post,release) for e in caps: v.evidence_identity(dict(binary_sha256=json.loads((d/'outcome.json').read_text())['evidence_provenance']['binary_sha256'],measurement_kind='raw'),CORE) assert e['sha256']==sha(e['path']) and e['output']==('HEADLESS-1' if e['tag'].endswith('H1') else 'HEADLESS-2') with Image.open(e['path']) as im:assert im.size==(800,600) ref=Image.open(d/'H2-reference1.png').convert('RGB') for name in ('H2-reference2','held-H2','natural-timeout-H2','restored-live-H2'):rgb_exact(ref,Image.open(d/(name+'.png')).convert('RGB')) assert max(e['end_ns'] for e in caps if e['tag'].startswith('held-'))done result['saved']=saved_raw() for rid in ('E0-pristine','E0-core','E2-vertical','E1','E4','E5','E6'): for p in (HIST/rid/'run').iterdir(): if p.is_file():result['files'][str(p)]=sha(p) return result if __name__=='__main__': r=replay();durable(LAB/'graphics/historical-replay.json',r);print(json.dumps({k:v for k,v in r.items() if k!='files'},indent=2))