"""Independent exact-arithmetic/source audit; does not execute numbered research."""
from pathlib import Path
from fractions import Fraction as F
import json,hashlib
R=Path(__file__).resolve().parent.parent
j=json.loads((R/'journal.json').read_text()); records={x['step']:x for x in j if 890<=x['step']<=900}
packet=json.loads((R/'model/covenant_inputs.json').read_text())
source=Path(packet['sources']['File63']['path']); txt=source.read_text()
checks={};details={}
checks['eleven_contiguous_records']=list(records)==list(range(890,901))
checks['all_bound_sources_match']=all(hashlib.sha256(Path(v['path']).read_bytes()).hexdigest()==v['sha256'] for v in packet['sources'].values())
def artifacts(x):
 if isinstance(x,dict):
  if set(('path','sha256','bytes'))<=set(x):yield x
  for y in x.values():yield from artifacts(y)
 elif isinstance(x,list):
  for y in x:yield from artifacts(y)
bindings=[a for rec in records.values() for a in artifacts(rec['results'])]
checks['all_current_artifact_bindings_match']=all((R/a['path']).is_file() and hashlib.sha256((R/a['path']).read_bytes()).hexdigest()==a['sha256'] and (R/a['path']).stat().st_size==a['bytes'] for a in bindings)
details['bound_artifacts']=len(bindings)
expected=[(14006,2006,12000,144000,146006),(14011,2006,12005,144060,146066),(14011,1936,12075,144900,146836),(14008,1933,12075,144900,146833),(14041,2081,11960,143520,145601),(14011,2051,11960,143520,145571)]
rows=json.loads((R/'model/six_macro_heads.json').read_text())
checks['six_literal_rows_match']=len(rows)==6 and [tuple(x[k] for k in ('C','R','span','body','M')) for x in rows]==expected
checks['six_anchored_lifts_exact']=all(C-T==s and 12*s==B and T+B==M and 12*C-11*T==M for C,T,s,B,M in expected)
checks['six_macro_output_formulas_literal_in_source']=all(t in txt for t in ('2006+144000=146006','2006+144060=146066','1936+144900=146836','1933+144900=146833','2081+143520=145601','2051+143520=145571'))
checks['lower_cumulative_pair_literal_in_source']='14008−1933=12075' in txt
checks['roles_preserved']='regular Jacob birth' in rows[0]['target_role'] and 'upper whole-year' in rows[2]['target_role'] and 'lower whole-year' in rows[3]['target_role'] and 'proposed' in rows[5]['target_role']
deltas=[]
for i,k in [(0,1),(1,2),(2,3),(4,5)]:
 a,b=expected[i],expected[k];dc=b[0]-a[0];dt=b[1]-a[1]
 deltas.append((dc,dt,b[3]-a[3],b[4]-a[4]))
checks['complete_response_field']=deltas==[(5,0,60,60),(0,-70,840,770),(-3,-3,0,-3),(-30,-30,0,-30)]
checks['response_law']=all(dm==12*dc-11*dt for dc,dt,db,dm in deltas)
details['independently_calculated_response']=deltas
checks['body_projection_loses_placement']=expected[2][3]==expected[3][3] and expected[2][4]!=expected[3][4] and expected[4][3]==expected[5][3] and expected[4][4]!=expected[5][4]
checks['body_plus_target_recovers_numeric_pair']=all(T+F(B,12)==C and T+B==M for C,T,s,B,M in expected)
pairs=[(14011,2051),(14006,2006),(14011,2006),(14011,1936)]
spans=[c-t for c,t in pairs];steps=[b-a for a,b in zip(spans,spans[1:])]
checks['ordered_carrier_source_rows']=spans==[11960,12000,12005,12075]
checks['ordered_incidence_changes']=steps==[40,5,70] and [(b[0]-a[0],b[1]-a[1]) for a,b in zip(pairs,pairs[1:])]==[(-5,-45),(5,0),(0,-70)]
checks['lifted_changes_complete']=[12*x for x in steps]==[480,60,840] and sum(steps)==115 and sum(12*x for x in steps)==1380
checks['hinge_exact_and_literal']=2166-2051==2051-1936==spans[-1]-spans[0]==115 and '2166−2051=115' in txt and '2051−1936=115' in txt
module=json.loads((R/'model/carrier_module_summary.json').read_text());hinge=json.loads((R/'model/carrier_115_hinge.json').read_text())
checks['proposed_offering_guard_preserved']='proposed' in hinge['roles'][1] and 'proposed offering date2051' in module['source_premises'] and 'Genesis 22 does not state Isaac’s age' in txt
checks['generated_heads_and_textual_total_guards']=any('not primary anchors' in x for x in module['limits']) and any('not textual variants' in x for x in module['limits'])
inp=144900;p=F(70,69)*inp;e=F(25,23)*inp
checks['terminal_branch_exact']=(inp,p,e)==(900*161,1000*147,900*175)
checks['terminal_gain_field']=(p-inp,e-inp,e-p)==(2100,12600,10500)
life=F(2083-1936);uniform=life*F(70,69);uniform_b=1936+uniform;preimage=life*F(69,70)
checks['retained_subdivision_literal']=148936-2083==999*147 and life==147 and '148936−2083=146853=999×147' in txt
checks['uniform_transport_comparison_exact']=uniform==F(3430,23)==149+F(3,23) and uniform_b==F(47958,23)==2085+F(3,23) and preimage==F(1449,10)
checks['uniform_transport_not_retention']=uniform_b-2083==F(49,23) and uniform_b!=2083
details['terminal_comparison']={'retained_partition':[146853,147],'uniform_P_life':str(uniform),'uniform_P_boundary':str(uniform_b),'displacement':str(uniform_b-2083),'preimage':str(preimage)}
a=[1-145601,1-2081,1-1];b=[1-145571,1-2051,30]
checks['civil_arm_partitions']=[a[1]-a[0],a[2]-a[1],a[2]-a[0]]==[143520,2080,145600] and [b[1]-b[0],b[2]-b[1],b[2]-b[0]]==[143520,2080,145600]
checks['complete_civil_translation']=[y-x for x,y in zip(a,b)]==[30,30,30]
checks['civil_no_year_zero']=1+30-1==30 and 2051+30-1==2080 and 145571+30-1==145600
details['source_phase_guard']='1936 is the source whole-year cumulative upper display, not exact1936.5. Cumulative and regular roles remain distinct.'
details['source_premise_guard']='Multiplier12, Covenant2081, proposed offering2051/Isaac age15, and external1BC/AD30 are source premises. Macro heads are generated, and144060/144900 are derived companions.'
out={'scope':'C890–C900 independent source and exact arithmetic review','status':'PASS' if all(checks.values()) else 'FAIL','checks':checks,'check_count':len(checks),'passed':sum(checks.values()),'details':details,'source63_sha256':hashlib.sha256(source.read_bytes()).hexdigest(),'C900_record_sha256':records[900]['sha256'],'corrections_required':[]}
(R/'evidence/INDEPENDENT_C890_C900.json').write_text(json.dumps(out,indent=2,ensure_ascii=False)+'\n')
print(json.dumps({'status':out['status'],'checks':len(checks),'passed':sum(checks.values()),'failed':[k for k,v in checks.items() if not v]}))
