19 lines
3.5 KiB
Python
19 lines
3.5 KiB
Python
from pathlib import Path
|
|
import json,gzip,hashlib,subprocess,shutil
|
|
r=Path('/Users/korizatou114/Projects/とりにく工房ゲーム制作部');e=r/'docs/plans/original-completion-2026-10-02/execution/drive-offload-p18-review-r08-20261015';m=json.loads(gzip.decompress((e/'MANIFEST.json.gz').read_bytes()));v=json.loads((e/'CLOUD_ALL_BYTES_VERIFIED.json').read_text());assert v['all_four_raw_bytes_identical']and v['all_new_objects_individually_verified']==188 and v['original_file_mappings']==8245
|
|
root=Path(m['source_root']);assert str(root)=='/Users/korizatou114/Projects/TheTree-managed-worktrees/p18-01-model/P18-01-CODE-review-7d78df63/.review-material';assert not root.is_symlink();trace=json.loads((r/'docs/plans/original-completion-2026-10-02/execution/p18-01-resume-20261015/RUNNER_BACKEND_COMPLETION_TRACEABILITY_265_R02.json').read_text());assert trace['implementation_commit']==m['candidate']and all(any(x['kind']==kind and x['passed']==1 and x['commit_sha']==commit for x in trace['evidence'])for kind,commit in [('review',m['candidate']),('final',trace['integration_commit'])])
|
|
assert json.loads((root/'manifest.json').read_text())['candidate']==m['candidate'];check=subprocess.run(['lsof','-nP','+D',str(root)],capture_output=True);assert check.returncode==1 and not check.stdout
|
|
expected={x['path']for x in m['members']if x['type']=='file'};actual={'.review-material/'+str(x.relative_to(root))for x in root.rglob('*')if x.is_file()};assert actual==expected
|
|
for x in m['members']:
|
|
p=root.parent/x['path'];assert not p.is_symlink();s=p.stat();assert s.st_mode&0o777==x['mode'] and s.st_mtime_ns==x['mtime_ns']
|
|
if x['type']=='file':
|
|
with p.open('rb')as f:h=hashlib.file_digest(f,'sha256').hexdigest()
|
|
assert h==x['sha256'] and s.st_size==x['bytes']
|
|
(e/'SOURCE_RECHECK.json').write_text(json.dumps({'all8245_file_bytes_modes_mtimes_exact':True,'no_open_files':True,'actual_cloud_readback_new_and_prior_objects_complete':True,'backend_normal_final_verified':True,'source_worktree_and_current_canonical_proof_excluded':True,'formal_original_credit':0},indent=2)+'\n')
|
|
before=shutil.disk_usage(r).free;quarantine=root.with_name('.review-material-retiring-r08');assert not quarantine.exists();root.rename(quarantine)
|
|
for x in m['members']:
|
|
if x['type']=='file':
|
|
p=quarantine/Path(x['path']).relative_to('.review-material');assert p.stat().st_mtime_ns==x['mtime_ns'];p.unlink()
|
|
for p in sorted([p for p in quarantine.rglob('*')if p.is_dir()],key=lambda p:len(p.parts),reverse=True):p.rmdir()
|
|
quarantine.rmdir();after=shutil.disk_usage(r).free;pointer=root.parent.with_name(root.parent.name+'.review-material.CLOUD_R08.json');pointer.write_text(json.dumps({'retired_source':str(root),'local_manifest':str(e/'MANIFEST.json.gz'),'cloud_files':v['files'],'restore_instructions':str(e/'RESTORE.md'),'prior_archives_required':list(m['archives']),'source_worktree_retained':True,'formal_original_credit':0},indent=2)+'\n');result={'retired_source':str(root),'files':8245,'logical_bytes':m['logical_bytes'],'free_before':before,'free_after':after,'net_free_delta':after-before,'new_archive_bytes':1800566,'all_restore_bytes_verified':True,'source_worktree_retained':root.parent.exists(),'current_canonical_proof_retained':Path('/Users/korizatou114/Projects/TheTree-managed-worktrees/p18-01-model/.runtime/P18-01-CODE/build/p18-relationship-evidence/receipt.json').exists(),'normal_run_and_traceability_records_retained':True,'pointer':str(pointer),'formal_original_credit':0};(e/'RETIREMENT.json').write_text(json.dumps(result,ensure_ascii=False,indent=2)+'\n');print(json.dumps(result,ensure_ascii=False))
|