16 lines
3.0 KiB
Python
16 lines
3.0 KiB
Python
from pathlib import Path
|
|
import gzip,hashlib,json,shutil,subprocess,time
|
|
R=Path('/Users/korizatou114/Projects/とりにく工房ゲーム制作部');E=R/'docs/plans/original-completion-2026-10-02/execution/drive-offload-p23-r14-r10-20261016';index=json.loads((E/'CLOUD_INDEX_VERIFIED.json').read_text());assert index['whole_raw_readback_verified'];parts=json.loads((E/'PARTS.json').read_text());assert parts['all_parts_cloud_raw_verified'];m=json.loads(gzip.decompress((E/'MANIFEST.json.gz').read_bytes()));S=Path(m['source']);assert S==R/'artifacts/original-completion-2026-10-02/p23-03-native-os-9a26f9a-r14';sha=lambda p:hashlib.file_digest(p.open('rb'),'sha256').hexdigest();actual={str(p.relative_to(S)) for p in S.rglob('*') if p.is_file()};assert actual=={z['path'] for z in m['files']}
|
|
for z in m['files']:
|
|
p=S/z['path'];s=p.stat();assert not p.is_symlink() and s.st_size==z['bytes'] and s.st_mode&0o777==z['mode'] and s.st_mtime_ns==z['mtime_ns'] and sha(p)==z['sha256']
|
|
opened=subprocess.run(['/usr/sbin/lsof','-nP','+D',str(S)],capture_output=True,text=True);assert opened.returncode==1 and not opened.stdout.strip() and not opened.stderr.strip(), 'source must have no open files'
|
|
for row in parts['parts']:
|
|
p=Path(row['path']);assert p.parent==Path('/private/tmp') and p.name.startswith('thetree-p23-r14-cold-r10.tar.gz.part') and p.stat().st_size==row['bytes'] and sha(p)==row['sha256']
|
|
(E/'SOURCE_RECHECK.json').write_text(json.dumps({'files':len(m['files']),'all_bytes_mode_mtime_exact':True,'source_has_no_open_files':True,'all_cloud_parts_and_restore_metadata_full_raw_verified':True,'archive_original_sha256':m['archive']['sha256']},indent=2)+'\n')
|
|
before=shutil.disk_usage(R).free
|
|
for z in m['files']:(S/z['path']).unlink()
|
|
for d in sorted((p for p in S.rglob('*')if p.is_dir()),key=lambda p:len(p.parts),reverse=True):d.rmdir()
|
|
assert not list(S.iterdir());pointer={'classification':'Ended failed P23 R14 raw proof moved to verified Drive parts; restore before raw review, no acceptance credit','index':index,'local_restore_metadata':str(E),'all_original_files':len(m['files']),'archive_sha256':m['archive']['sha256']};(S/'CLOUD_R10.json').write_text(json.dumps(pointer,indent=2)+'\n')
|
|
for row in parts['parts']:Path(row['path']).unlink()
|
|
after=shutil.disk_usage(R).free;result={'retired_source':str(S),'files':len(m['files']),'logical_bytes':sum(z['bytes']for z in m['files']),'source_free_before_retirement':before,'free_after_retirement':after,'measured_delta_including_temp_part_removal':after-before,'temporary_parts_bytes_removed':m['archive']['bytes'],'measured_delta_excluding_temp_part_bytes':after-before-m['archive']['bytes'],'free_before_archive_preparation':m['free_before_archive'],'net_free_change_since_preparation':after-m['free_before_archive'],'all_cloud_parts_raw_verified':True,'all_restore_metadata_raw_verified':True,'original_failed_status_preserved':True,'source_and_current_work_proofs_untouched':True,'formal_credit':0};(E/'RETIREMENT.json').write_text(json.dumps(result,indent=2)+'\n');print(result)
|