"""Descriptive paired reanalysis of published predictions; no model call.
Run: python3 analyze-errors.py PATH_TO_2026-11-01_DATA OUTPUT_JSON
Only Python standard library. Identical inputs produce identical output.
"""
import json,sys,hashlib,platform
from pathlib import Path
from collections import Counter
p=Path(sys.argv[1]);f=p/'routing-predictions-final.json';rows=json.loads(f.read_text())
print('Prediction fields:',sorted(rows[0]))
old='bm25_or_none';new='bm25_name_description';pairs=Counter()
for r in rows:
 a=r[old]==r['gold'];b=r[new]==r['gold'];pairs[('both_correct' if a and b else 'regression' if a else 'correction' if b else 'both_wrong')]+=1
out={'method':'Paired descriptive reanalysis of already published fixed predictions. No new model or product run. No population significance claim.','sample_n':len(rows),'source_sha256':hashlib.sha256(f.read_bytes()).hexdigest(),'python':platform.python_version(),'comparison':{'before':old,'after':new},'paired_correctness':dict(sorted(pairs.items())),'errors':{}}
for method in [old,new]:
 c=Counter()
 for r in rows:
  gold,pred=r['gold'],r[method]
  c['correct' if gold==pred else 'unnecessary_tool' if gold=='none' else 'missed_tool' if pred=='none' else 'wrong_tool']+=1
 out['errors'][method]=dict(sorted(c.items()))
out['none_gold_n']=sum(r['gold']=='none' for r in rows);out['tool_gold_n']=len(rows)-out['none_gold_n']
Path(sys.argv[2]).write_text(json.dumps(out,ensure_ascii=False,indent=2)+'\n');print(json.dumps(out,ensure_ascii=False))
