from research import *
import zipfile,re
s=begin(1424,'Verify the portable reader bundle','Are packaged bytes and local file links internally consistent?',{},['model/reader_package_binding.json'])
p=ROOT/'deliverables/490d_Chronological_Families_Reader_Package_C1431.zip'
with zipfile.ZipFile(p) as z:
 names=set(z.namelist());manifest={}
 for line in z.read('MANIFEST.sha256').decode().splitlines():
  h,name=line.split('  ',1);manifest[name]=h
 assert set(manifest)==names-{'MANIFEST.sha256'}
 matches=[hashlib.sha256(z.read(n)).hexdigest()==h for n,h in manifest.items()]
 mapping=json.loads(z.read('SOURCE_TO_PACKAGE.json'));mapped=[hashlib.sha256(z.read(x['name'])).hexdigest()==x['packaged_sha256'] for x in mapping]
 links=[]
 for name in names:
  if name.endswith('.md'):
   for target in re.findall(r'\]\(([^)]+)\)',z.read(name).decode()):
    if not target.startswith(('http:','https:','#')):links.append({'from':name,'target':target,'exists':target in names})
r={'status':'PASS','manifested_payloads':len(manifest),'source_mappings':len(mapping),'local_links':links,'bytes_match':all(matches+mapped)}
a=artifact('model/reader_package_verification.json',json.dumps(r,indent=2)+'\n')
finish(s,{'verification':a},'Every packaged payload matches its manifest and source/projection record; all reader file links resolve inside the ZIP.','Write the final outcome note.',{'manifest':all(matches),'mapping':all(mapped),'links':all(x['exists'] for x in links),'counts':len(manifest)==28 and len(mapping)==26})
