64 lines
3.8 KiB
Python
64 lines
3.8 KiB
Python
"""Create a separate final-review supplement without modifying the first packet."""
|
|
from pathlib import Path
|
|
import hashlib,json,runpy,zipfile
|
|
|
|
ROOT=Path('C:/ar-focus-01a0d717')
|
|
OUT=Path(__file__).resolve().parent
|
|
sha=lambda data:hashlib.sha256(data).hexdigest()
|
|
|
|
def main():
|
|
original_index=OUT/'index.json'
|
|
assert sha(original_index.read_bytes())=='a632f68e43ae8cfbbe87092f8023d80bcc9c2f29079e56b7f09b83fa3628d1e2'
|
|
original=json.loads(original_index.read_bytes())
|
|
def verify_original():
|
|
for item in original['files']:
|
|
data=(OUT/item['path']).read_bytes()
|
|
assert len(data)==item['bytes'] and sha(data)==item['sha256'],item['path']
|
|
assert sha(original_index.read_bytes())=='a632f68e43ae8cfbbe87092f8023d80bcc9c2f29079e56b7f09b83fa3628d1e2'
|
|
verify_original()
|
|
helpers=runpy.run_path(str(OUT/'collect.py'))
|
|
local=ROOT/'.local'
|
|
assert sha((local/'focus-native/parent-observations.json').read_bytes())=='73189f8a597d52e893ccc23ba0ed11cc4bec99d2ec07b45f7d5c52772d44de72'
|
|
corpus=local/'focus-final-review-dwb4lmy7'
|
|
sources=[(p,p.relative_to(local).as_posix()) for p in corpus.rglob('*') if p.is_file()]
|
|
extra=['focus-final-review-probe.py','focus-final-oracle-review.md','focus-native/parent-observations.json','write-focus-observations.py']
|
|
sources.extend((local/name,name) for name in extra)
|
|
supplement=helpers['archive']('supplemental-final-review.zip',sources)
|
|
copies=[helpers['copy'](local/'focus-final-oracle-review.md','reviews/final-review.md'),
|
|
helpers['copy'](local/'focus-native/parent-observations.json','parent-observations.json')]
|
|
verify_original()
|
|
files=[helpers['record'](p) for p in sorted(OUT.rglob('*')) if p.is_file()]
|
|
archives=original['archives']+[supplement]
|
|
final={'source':original['source'],
|
|
'scope':'Final content inventory, not an experiment verdict. Includes the first packet unchanged plus a separate final-review/parent-observation supplement. This index excludes only its own recursively unhashable entry.',
|
|
'original_index':helpers['record'](original_index),
|
|
'original_packet_unchanged':True,
|
|
'supplement_scope':'The formerly pending fresh repair review is now included, with its complete private probe corpus and the later parent observation receipt. Historical provenance text and raw filenames remain unchanged.',
|
|
'standalone_file_count':len(files),'standalone_bytes':sum(r['bytes'] for r in files),'files':files,
|
|
'archives':archives,'archived_member_count':sum(a['member_count'] for a in archives),
|
|
'archived_uncompressed_bytes':sum(a['uncompressed_bytes'] for a in archives),
|
|
'copied_sources':original['copied_sources']+copies,'skipped':original['skipped'],
|
|
'supplement_skipped':[]}
|
|
helpers['emit'](OUT/'index-final.json',final)
|
|
# Independently read back the newly added ZIP and compare every original source.
|
|
manifest=json.loads((OUT/supplement['member_inventory']['path']).read_bytes())
|
|
with zipfile.ZipFile(OUT/supplement['archive']['path']) as archive:
|
|
assert set(archive.namelist())=={item['path'] for item in manifest['members']}
|
|
for item in manifest['members']:
|
|
data=archive.read(item['path'])
|
|
assert len(data)==item['bytes'] and sha(data)==item['sha256']
|
|
assert data==Path(item['original_source_path']).read_bytes()
|
|
for item in files:
|
|
data=(OUT/item['path']).read_bytes()
|
|
assert len(data)==item['bytes'] and sha(data)==item['sha256']
|
|
verify_original()
|
|
print(json.dumps({'index_final':helpers['record'](OUT/'index-final.json'),
|
|
'supplement':supplement,'standalone_copies':copies,
|
|
'files_including_final_index':len(files)+1,
|
|
'bytes_including_final_index':sum(r['bytes'] for r in files)+(OUT/'index-final.json').stat().st_size,
|
|
'all_archived_member_count':final['archived_member_count'],
|
|
'all_archived_uncompressed_bytes':final['archived_uncompressed_bytes'],
|
|
'original_packet_unchanged':True,'supplement_skipped':[]},indent=2))
|
|
|
|
if __name__=='__main__':main()
|