import csv,hashlib,json
from pathlib import Path
root=Path(__file__).resolve().parent
def require(v,m):
 if not v:raise ValueError(m)
manifest=json.loads((root/'manifest.json').read_text())
for name,sha in manifest.items():
 p=(root/name).resolve();require(p.is_relative_to(root) and hashlib.sha256(p.read_bytes()).hexdigest()==sha,'Manifest mismatch')
d=json.loads((root/'finding.json').read_text());require(len(d['findings'])==8,'Observation coverage')
for f in d['findings']:
 rows=list(csv.DictReader((root/f['source_locator']['file']).open(newline='')));require(len(rows)==1,'Expected one city row');r=rows[0];require(r['GEO_ID']=='1600000US0644000','Wrong geography')
 m=f['method'];table=m['table'];n=sum(int(r[f'{table}_E{i:03d}']) for i in m['numerator_fields']);den=sum((1 if i>0 else -1)*int(r[f'{table}_E{abs(i):03d}']) for i in m['denominator_fields'])
 require(n==f['estimate']['numerator'] and den==f['estimate']['denominator'] and 0<=n<=den and den>0,'Operand mismatch');require(round(100*n/den,2)==f['estimate']['value_percent'],'Ratio mismatch');require(f['derived_ratio_moe_90'] is None,'Unsupported uncertainty claim')
print('PASS8 exact-city observations, source-row arithmetic and manifest hashes. No network refresh, statistical significance, causality or current-source certification.')
