import json,pathlib
from PIL import Image,ImageChops
R=pathlib.Path('/tmp/lead-33036-r2/evidence-capture-2/20261110-gap');M=json.loads((R/'selected-manifest.json').read_text())
for row,m in M.items():
 assert {'before','after'}<=m.keys(),row
 for side in ['before','after']:
  assert m[side]['environment']['viewport']=={'width':1440,'height':900}
  assert m[side]['environment']['dpr']==(2 if row.startswith('R05') else 1)
  assert not any('wheel' in e['action'].lower() for e in m[side]['events']) if row=='R07' else True
 if row in ['R04bottom','R04assistant','R07']:
  a=m['before']['events'];b=m['after']['events'];assert len(a)==len(b),(row,len(a),len(b))
  for x,y in zip(a,b):
   for field in ['action','scrollTop','maxScroll','viewport','rows','ticks','selection','previousDisabled','nextDisabled']:
    assert x[field]==y[field],(row,field,x['action'],x[field],y[field])
  assert all(d['diff0']['changedPixels']==0 for d in m['diffs'].values()),row
 if row=='R07':
  for side in ['before','after']:
   end=next(e for e in m[side]['events'] if e['action']=='still:settled')
   assert end['maxScroll']-end['scrollTop']==180
   assert end['selection']['current']=='turn-4' and end['nextDisabled']
 if row.startswith('R05'):
  for extra in ['', '-boundary25', '-boundary25-5']:
   p=R/'deliverables'/f'{row}-before{extra}.png';q=R/'deliverables'/f'{row}-after{extra}.png'
   if not p.exists():continue
   d=ImageChops.difference(Image.open(p).convert('RGB'),Image.open(q).convert('RGB'))
   assert d.crop((800,720,1440,770)).getbbox() is None,(row,extra,'badge differs')
  if row=='R05b':assert m['diffs']['-boundary25-5']['diff0']['changedPixels']==0
 print(row,'verified',flush=True)
(R/'capture-audit.txt').write_text('Synthetic content equality verified separately.\nAll six gap scene pairs: viewport, DPR, equal controls, target/tick states and R05 badge checks passed.\nR07: Next-only endpoint, 180px before maximum, pre-existing composer occlusion on both revisions.\n')
