"""Read-only independent review of root C1253–1264; writes NEW prep review files."""
from pathlib import Path
from fractions import Fraction as F
from itertools import product
import re,json,hashlib,datetime
B=Path(__file__).resolve().parents[1]
source18=B/'evidence/sources/38-File_18.Chronological_Data_Tables-20260919-141048-.md'
source07=B/'evidence/sources/22-File_07.Creation_Seed_Decimal_Root-1-1-.md'
s=source18.read_text(); f07=source07.read_text()
def table(a,b):
 t=s[s.index(a):s.index(b,s.index(a))];rows={}
 for line in t.splitlines():
  if line.startswith('|'):
   c=[x.strip().replace('`','') for x in line.strip('|').split('|')]
   if len(c)==5 and c[1].isdigit() and c[-1].split('/')[0].isdigit(): rows[c[0]]={'birth':int(c[1]),'b':int(c[-1].split('/')[0])}
 return rows
mt=table('#### 2.1.3 MT Minimum-Regular table','#### 2.2.1 Noah and Shem')
lxx=table('### 4.1 Creation to Flood: LXX Regular-Minimum','### 4.3 Patriarchal period: LXX')
names=list(mt); changes=[lxx[n]['b']-mt[n]['b'] for n in names]
field=[sum(changes[i:]) for i in range(20)]
j=names.index('Arphaxad');native=[lxx[n]['birth']-mt[n]['birth'] for n in names]+[0]
models={p.stem:json.loads(p.read_text()) for p in sorted((B/'model').glob('regular_kernel_*.json'))}
stair=models['regular_kernel_complete_staircase']; ns=models['regular_kernel_native_staircase']
variants=sorted([dict(T=t,C=c,S=z,offset=60*t+130*c+215*z) for t,c,z in product([0,1],repeat=3)],key=lambda x:x['offset'])
literals={}
block=f07[f07.index('#### 2.11.1a'):f07.index('Flood-side width note:',f07.index('#### 2.11.1a'))]
for line in block.splitlines():
 c=[x.strip() for x in line.strip('|').split('|')]
 if len(c)==4 and re.fullmatch(r'\d+ BC',c[0]):
  y,e=int(c[0].split()[0]),int(c[1].split()[0]);lit=c[2]
  literals[y]={'Year6':y,'endpoint':e,'T':int('+60' in lit),'C':int('restored' in lit),'S':int('+215' in lit),'raw':line}
expected_states=[]
for v in variants:
 y=3901+v['offset']; expected_states.append((v,literals[y]))
reader=B/'deliverables/Regular_Kernel_Two_Source_Mechanisms.md';body=reader.read_text()
cal=models['regular_kernel_five_calibration']; coeff=models['regular_kernel_common_coefficient'];sp=models['regular_kernel_SP_local_mechanism']
checks={
 'source_common_rows19':len(mt)==len(lxx)==19,
 'source_row_changes_match':changes==stair['local_begetting_changes'],
 'source_field20_match':field==stair['field'] and stair['labels']==names+['Abraham'],
 'adjacent_recovery':all(field[i]-field[i+1]==changes[i] for i in range(19)),
 'six_pre_centuries':sum(changes[:9])==600 and sum(x==100 for x in changes[:9])==6,
 'six_post_centuries_half':sum(changes[10:])==650 and sum(x==100 for x in changes[10:])==6 and changes[names.index('Nahor')]==50,
 'field_head_and_plateau':field[0]==1250 and all(field[names.index(n)]==650 for n in ['Noah','Shem','Arphaxad']),
 'literal_native_field':native==ns['native_shared_boundary_field'],
 'native_insertion_support':native==[x+(130 if i<=j else 0) for i,x in enumerate(field)],
 'native_and_OFF_heads':native[0]==1380 and native[j]==780 and field[0]==1250 and field[j]==650,
 'eight_literal_rows':len(literals)==8,
 'eight_literal_state_bits':all(all(v[k]==lit[k] for k in ['T','C','S']) for v,lit in expected_states),
 'eight_literal_endpoint_roles':all(lit['Year6']-lit['endpoint']==2 and lit['endpoint']==3899+v['offset'] for v,lit in expected_states),
 'offsets_match':[v['offset'] for v in variants]==models['regular_kernel_eight_state_field']['ordered_offsets'],
 'gap_word':[variants[i+1]['offset']-variants[i]['offset'] for i in range(7)]==[60,70,60,25,60,70,60],
 'TC_restriction':[v['offset'] for v in variants if not v['S']]==[0,60,130,190],
 'TS_restriction':[v['offset'] for v in variants if not v['C']]==[0,60,215,275],
 'width_no_five':215+60+130==models['regular_kernel_eight_state_field']['width']==405,
 'invertible_two_equations':10*5-5*0==50,
 'coefficient_solution':F(cal['solution']['T_over_u'])==F(3,5) and F(cal['solution']['C_over_u'])==F(13,10),
 'symbolic_five_equations':10*F(3,5)+5*F(13,10)==F(25,2) and 5*F(13,10)==F(13,2),
 'free_kappa_elimination':25-13==12 and F(12,26)==F(6,13) and F(13*100,2*130)==5,
 'free_kappa_scope':'nonzero' in coeff['assumptions'] and 'positive' in coeff['assumptions'],
 'Sojourn_absent_from_calibration':'SojournS doesnotappear'==cal['not_constrained'],
 'sum_difference_not_extra':F(1250+650,2)==950 and F(1250-650,2)==300,
 'SP_named_losses':sp['source_located_losses']=={'Jared':100,'Methuselah':120,'Lamech_completed':130},
 'SP_one_count':182-53+1==182-52==130 and sp['Lamech_count_bridge']=={'nominal_age_difference':129,'counted53rd_to_completed52':1,'completed_difference':130},
 'SP_source_primary_binding':'3545−52=3493' in s and '3493−600=2893' in s,
 'SP_companion_counts_one_once':52+500+100==53+499+100==53+500+99==652,
 'SP_source_Creation_and_Flood':650-(100+120+130)==4199-3899==300 and 2893-2243==650,
 'covariance_all_support_blocks':all(((1000+60*t*mtk+130*c*mck+215*z*msk)-(60*t*mtk+130*c*mck+215*z*msk)==1000) for mtk,mck,msk in [(1,1,1),(1,0,1),(0,0,1),(0,0,0)] for t,c,z in product([0,1],repeat=3)),
 'reader_no_origin_claim':'does not establish a historical rule' in body,
 'reader_two_layer_condition':'C=13u/10 and T=3u/5' in body and 'does not itself generate the ratios' in body,
}
journal=json.loads((B/'journal.json').read_text());selected=[x for x in journal if 1253<=x['step']<=1264]
artifact_hashes=[]
for st in selected:
 for val in st['results'].values():
  if isinstance(val,dict) and 'path' in val and 'sha256' in val:
   p=B/val['path']; artifact_hashes.append(hashlib.sha256(p.read_bytes()).hexdigest()==val['sha256'])
checks['twelve_closed_steps']=len(selected)==12 and all('closed_utc' in x for x in selected)
checks['all_recorded_artifact_hashes']=all(artifact_hashes) and len(artifact_hashes)==12
checkpoint=json.loads((B/'deliverables/Block_03_C1232_C1281_Checkpoint.json').read_text())
rbind=next(x for x in checkpoint['bound_results'] if x['path'].endswith('Regular_Kernel_Two_Source_Mechanisms.md'))
checks['C1281_reader_binding']=hashlib.sha256(reader.read_bytes()).hexdigest()==rbind['sha256']
assert all(checks.values())
findings=[
 {'id':'R1','severity':'low','type':'reader_scope','location':'Regular_Kernel_Two_Source_Mechanisms.md:5','finding':'The first1250/650 comparison omits its matched-Cainan/OFF label until the later native sentence. The model has the scope correctly.','suggested_copy':'First, the ordered shared MT–LXX rows, with Cainan matched OFF for this comparison, generate a complete Regular displacement field.','blocking':False},
 {'id':'R2','severity':'low','type':'evidence_wording','location':'Regular_Kernel_Two_Source_Mechanisms.md:11','finding':'“Independently supplied Sojourn215” can be read as an independence claim; the demonstrated point is thatS is separately sourced and absent from the two equations.','suggested_copy':'The separately sourced Sojourn interval215 is not constrained by these two relations.','blocking':False},
 {'id':'R3','severity':'low','type':'primitive_register','location':'C1253 checks.four_primitives; model/regular_kernel_two_mechanisms.json; final synthesis register','finding':'u=100 is a summary parameter extracted from retained paired source rows. If those rows are already retained, do not countu again as an independent primitive. The same applies to derivedcalibration and totals.','suggested_copy':'u=100 summarizes the repeated begetting differences; the named supports and source rows remain its evidence.','blocking':False},
 {'id':'R4','severity':'low','type':'presentation','location':'Reader draft throughout','finding':'Restore spaces around numbers and words in final copy; typeset the two calibration equations as a single displayed pair. This does not require historical file edits.','blocking':False},
]
register=[
 {'bundle':'Ordered source rows','retain':'Names,order,tradition; selectedb andL with source statuses; nativeCainan incidence; currentLXX182/753;SPinclusive flags and effective binding corrections.','examples':['Adam MTb130','Cainan LXXb130,L460','Terah selectedb70/130','Lamech SP53rdcounted→52completed'],'derived_not_extra':'r=L−b; all row differences; fittedu100 andother amplitude summaries; accumulated dates if constructed from retainedrows/terminal.','source':'File18; complete_source_row_packet.json'},
 {'bundle':'Admitted state and placement choices','retain':'Role-keyedTerahT,Regular/CumulativeCainan measure,SojournS,source support masks,finite labels,andnative-versus-comparison selections.','examples':['T_Terah=60 from205−75−70','Cainan insertion readsb130 orL460','S_Sojourn=215 withExodusheld'],'derived_not_extra':'190/275/405 offsets,gap70,gap25;fivefoldcalibration recorded as observed relation,not originrule.','source':'File04§2.4;File18§§1.3.1,1.6;File00§3.3.1;File07§2.11.1a'},
 {'bundle':'Terminals and counting conventions','retain':'Each adopted anchor with event/node class,mode,frame andcount rule; SPnativeG2 and600toFlood;inclusive+1;actualcompletion/Year6 choices;civil versusRounded crossing.','examples':['Exodus1446','Conquest/Mosesdeath1406 initsdeclaredrole','Nativity6','SPNoah3493 andFloodstart2893 asoneboundsourceplacement'],'derived_not_extra':'Store onechosen independentplacement basis per localmodule; otherconnected dates are generated/cached.600+1=601 is derived.','source':'File18sourcebindings;File51a;File52c;inheritedC1131junctionpacket'},
 {'bundle':'Rounded observations and retained subdivisions','retain':'Which sourcequantity isrounded,theQ5rule,andtheexactsource-appointedcuts;residuals onlywhere required byan explicitinverseobservation problem.','examples':['Regular1650|1050 andCumulative9170|3430 are generatedboundary interfaces withretainedcutroles','Moses13-edgepath and4|9 grouping'],'derived_not_extra':'Roundedvalues,residuals,carryandfibre sizes whencomputedfromrawrows;do notcountbothrows andtheirownroundedoutputs asindependenttestimony.','source':'File51a§§3.1,7A,16;currentRoundedmodels'},
 {'bundle':'Covenant biographies and calendar operations','retain':'Namedlocalbiographies/ages,phase/terminalchoices,exactE/P/Jratios,theirunitmeasures,andwhichpathparts areconverted orretained.','examples':['Jacoblife147','LeviandIshmael137 roles','E25/23 pairedwith336;P70/69 with360;J300/299 with364'],'derived_not_extra':'Clutchcoordinates,sharedlandings,commongain,allocationfractionsandtotals;calibrationequationsbelonginrelationscolumn.','source':'Files60–63;inheritedC1131Covenant/Keyregister'},
 {'bundle':'NT,counted andliterary structures','retain':'Namedslotorder,multiplicity/categories,source-selectedmetricandhinge;whichmeasurecounts names,intervals,sections oroccurrences.','examples':['NTcarrier70','Lukehinge6','nativeCainanpersonlabeldistinctfrom70-yearslotmeasurement'],'derived_not_extra':'Displaydates,490coarsening,Keyreturnindices;samevalue70inTerahageandderivedvariantgapdoesnotmergewithNTmetric.','source':'Files43/54/58/69/70;existingfullsourcepackets'},
 {'bundle':'First decimal-inverse interface','retain':'Base10,placeholderpolicy,sourcecomponentcuts,first-reversal selectoranchorsandadmittedmembermanifest.','examples':['File52cConquest1406versus1401selectorrole','Original1400completionleg'],'derived_not_extra':'Inverseendpoints10620/12026/14726 anddigitgains;theyareoutputchecks,notadditionalglobalprimitive inputs.','source':'LatestFile52c;inheritedcomplete32pairedfieldandprimarypaths'},
]
collision_examples=[
 {'value':130,'separate_roles':['MTAdam begetting','secondCainan begetting','selectedTerah begetting','derivedMosesprefix130'],'rule':'Keep the firstthree source roles distinct; thelast is a generated sum.'},
 {'value':60,'separate_roles':['Terah variant','Isaac begetting','Nahor MT/LXX lifespan difference','SP Eber/Terah lifespan differences'],'rule':'Shared fitted amplitudes may encode numeric equality but do not replace source-role provenance.'},
 {'value':100,'separate_roles':['repeated MT/LXX differenceu','Abraham begetting','sourceNoah/Shem local interval'],'rule':'Do not promote one role to generator ofthe others without an admittedsource relation.'},
 {'value':70,'separate_roles':['NTslotmetric','Terah minimum begetting','derivedC−T gap'],'rule':'Only the firsttwo can be retainedsource inputs in their modules;thelast is a consequence.'},
 {'value':460,'separate_roles':['Cainan lifespan','Covenant299+161 total','SPfirstfive begetting sum'],'rule':'One life input andtwo labelled pathmeasurements are not one interchangeableoperation.'},
 {'value':950,'separate_roles':['Noah lifespan','derivedmidpoint of1250/650'],'rule':'Record source datum andcomparisonrelation,not two independent primitive950s.'},
]
inputs=[source18,source07,reader,B/'prep/regular_kernel_source_cost.json',B/'inherited/Primitive_Data_Register_C1131.json',B/'deliverables/Block_03_C1232_C1281_Checkpoint.json']+list(sorted((B/'model').glob('regular_kernel_*.json')))+[B/f'evidence/s{i}.py' for i in range(1253,1265)]
report={'status':'PASS_WITH_MINOR_READER_CLARIFICATIONS','scope':'Independent review ofC1253–1264 journal,all12scripts,11models,reader andC1281binding. No rootsources,journal,models ordeliverables changed.','created_utc':datetime.datetime.now(datetime.timezone.utc).isoformat(),'checks':checks,'check_count':len(checks),'arithmetic_errors':[],'blocking_findings':[],'findings':findings,'source_evidence':{'row_tables':'File18§§2.1.3–2.2,4.1–4.2;directparserusesliteralbirths andbegettingages.','eight_states':'File07§2.11.1a literalrows991–998; bothcoordinatecolumnsandallvariantlabels independentlychecked.','SP':'File18§3.1,literal52/53paths andsameFloodstart.','calibration':'ExactFractionelimination;not replayingrootresearch.begin/finish.'},'verified_conclusions':['All20boundarydifferences reconstruct directlyfromliteralMT/LXXrows.','NativeCainan changesonlythedeclaredprefixby130.','Both190/275restrictionsandthe405envelopearefullysourcebound.','CoefficientfiveiffT=3u/5,C=13u/10;arbitrarycommoncoefficientiff6C=13T fornonzerosource scales.','S is not constrained bythose twoequations.','SP129+1 is one completed-count adjustment,not a secondFloodyear.','Thepositive explanation joins two mechanisms; nohistoricalgenerationofagesclaimed.'],'primitive_register_proposal':{'principle':'Use role-keyed sourceinputs plus operationchoices. Separate derivedoperational summaries/interfacecaches from globalprimitive evidence. Preserve sourcepacketrefs ratherthanrepeatingeveryvalue.','fields':['id','value_or_packet_ref','unit_and_measure','subject_and_order','mode_state_scope','source_ref','status_given_reconstructed_or_derived','derived_from'],'bundles':register,'same_value_different_roles':collision_examples,'not_a_new_campaign':'This is editorial consolidation ofexistingcertifiedpackets; no new numericalsearch orminimizationtheorem proposed.'},'input_sha256':{str(p.relative_to(B)):{'sha256':hashlib.sha256(p.read_bytes()).hexdigest(),'bytes':p.stat().st_size} for p in inputs},'journal_step_hashes':{str(x['step']):x['sha256'] for x in selected}}
p=B/'prep/review1253_1264.json';assert not p.exists();p.write_text(json.dumps(report,indent=2,ensure_ascii=False)+'\n')
md=['# Independent review of C1253–C1264','','**Status: PASS with minor reader clarifications.** All '+str(len(checks))+' independent checks pass. No arithmetic error or blocking scope error was found. No root files were changed.','','## What was checked','','The review rederived all nineteen shared begetting differences and twenty boundary differences from the literal File18 tables, independently of the adopted row model. It also recovered the native comparison directly from printed birth dates. File07’s eight literal rows were checked for their two coordinate columns and all three variant labels. Exact fraction calculations verified both coefficient statements. SP’s three local count paths were checked against the source. All twelve recorded artifact hashes and the C1281 reader binding agree.','','The key results are sound: the row mechanism generates1250/650; the finite placement mechanism generates405; their fivefold relation requiresT=3u/5 andC=13u/10. A free common coefficient requires6C=13T under the stated nonzero conditions. SojournS remains unconstrained. The SP correction converts the counted53rd year to52 completed units once, giving100+120+130=350 and650−350=300.','','## Small refinements for the final copy','']
for x in findings:
 md += [f"- **{x['id']} — {x['location']}.** {x['finding']}"+(f" Suggested wording: “{x['suggested_copy']}”" if x.get('suggested_copy') else '')]
md += ['','The wording “observed numerical relation among these source values” may replace “received calibration” if a plainer closing sentence is preferred. The present calibration language is mathematically justified. The reader correctly avoids claiming that the kernel originated the ancestral ages.','','## Concise primitive-data register for the final synthesis','','Use a role-keyed register with these fields: **ID · value or packet reference · measure/unit · subject/order · mode/state/scope · source · given/reconstructed/derived status · dependencies**. A compact register can point to the certified source packets rather than recopy every row. It should distinguish global source premises from cached inputs used at a later module boundary.','','| Retained bundle | What must remain explicit | What should stay derived |','|---|---|---|']
for x in register:
 md += ['| '+x['bundle']+' | '+x['retain']+' | '+x['derived_not_extra']+' |']
md += ['','Equal values must remain attached to their roles:','','| Value | Roles to retain | Treatment |','|---:|---|---|']
for x in collision_examples:md += ['| '+str(x['value'])+' | '+'; '.join(x['separate_roles'])+' | '+x['rule']+' |']
md += ['','The important register change from C1131 is classification, not another numerical campaign. In particular, source-generated Rounded coordinates, inverse endpoints, residuals and fitted amplitude summaries should not become additional independent premises merely because another module reads them. They can remain named interface values with dependency links. The source-appointed cuts, names, count rules and operator choices that generate them remain visible.','','## Evidence record','','The JSON companion records every check, all reviewed input SHA256 values and the twelve frozen journal-step hashes. Principal source sections are File18 §§2.1.3–2.2,3.1,4.1–4.2 and File07 §2.11.1a. The review did not run root mutation scripts or open additional chronology branches.']
m=B/'prep/review1253_1264.md';assert not m.exists();m.write_text('\n'.join(md)+'\n')
print(json.dumps({'status':report['status'],'checks':len(checks),'json_sha256':hashlib.sha256(p.read_bytes()).hexdigest(),'markdown_sha256':hashlib.sha256(m.read_bytes()).hexdigest()},indent=2))
