from pathlib import Path
import json
root=Path('artifacts/exchange-redesign-20260908')
def read(version, workload):
 rows={}
 for line in (root/f'{version}-{workload}.log').read_text().splitlines():
  if line.startswith('phase='):
   d=dict(field.split('=',1) for field in line.split());rows[int(d['phase'])]=d
 return rows
lines=['| Capture / phase | Transfers | Baseline seconds | Final seconds | Speedup | Cycles | Max row bytes |','|---|---:|---:|---:|---:|---:|---:|']
metrics=[]
for workload in ['b2','b4','b4-million','mlp','attention']:
 before=read('baseline',workload);after=read('final',workload);staged=read('staged',workload)
 assert before.keys()==after.keys()==staged.keys(),workload
 for phase, row in after.items():
  old=before[phase]
  for key in ['horizonCycles','rowWords','maximumRowWords']:
   assert row[key]==old[key],(workload,phase,key)
  if workload != 'mlp' or phase != 1:
   assert row['rowFingerprint']==staged[phase]['rowFingerprint'],(workload,phase)
  baseline=float(old['scheduleCodegenMinMs'])/1000; final=float(row['scheduleCodegenMinMs'])/1000
  if workload in ['b2','b4','b4-million']:
   lines.append(f"| {workload} / {phase} | {int(row['transfers']):,} | {baseline:.2f} | {final:.2f} | {baseline/final:.2f}× | {int(row['horizonCycles']):,} | {int(row['maximumRowWords'])*4:,} |")
  metrics.append({'workload':workload,'phase':phase,'baselineSeconds':baseline,'finalSeconds':final,**row})
 print(workload,'phases',len(after),'baseline',round(sum(float(x['scheduleCodegenMinMs']) for x in before.values())/1000,3),'final',round(sum(float(x['scheduleCodegenMinMs']) for x in after.values())/1000,3),'baseline metrics preserved; fingerprints checked (MLP phase 1 restores baseline)')
p=Path('docs/EXCHANGE_SCHEDULER_BENCHMARKS_2026_09_08.md');s=p.read_text(); start=s.index('| Capture / phase |'); end=s.index('\n\nAll six large-phase', start); s=s[:start]+'\n'.join(lines)+s[end:]; p.write_text(s)
(root/'results.json').write_text(json.dumps(metrics,indent=2)+'\n')
(root/'validation-summary.txt').write_text('All baseline horizons and total/max row sizes match final results.\nFinal row fingerprints match staged rows except MLP phase 1, which restores the baseline improvement.\n'+str(len(metrics))+' phases checked across three ViT captures, MLP and attention.\n')
print('\n'.join(lines))
