from pathlib import Path
import json,hashlib,shutil
W=Path('/mnt/data/work4100');R=W/'site';E=R/'доказательства/редакция-4.10.0'
rows=[]
for kind in ['память-уаикс','документы-и-доказательства','набор-владельца']:
 base=W/'input'/(kind+'-4.9.0')
 for p in sorted(base.rglob('*')):
  if not p.is_file() or p.suffix=='.pyc' or '__pycache__' in p.parts:continue
  rel=p.relative_to(base);dest=R/rel;raw=p.read_bytes()
  if dest.is_file() and dest.read_bytes()==raw:target=rel
  else:
   # Retain exact bytes as an explicitly archived non-public representation.
   target=Path('docs/архив-выпусков/4.9.0-различающиеся-байты')/kind/(rel.as_posix()+'.txt');q=R/target;q.parent.mkdir(parents=True,exist_ok=True);q.write_bytes(raw)
  rows.append({'набор':kind,'исходный_путь':rel.as_posix(),'путь_сохранённых_байтов':target.as_posix(),'байты':len(raw),'SHA256':hashlib.sha256(raw).hexdigest()})
(E/'сохранённые-байты-наборов-4.9.0.json').write_text(json.dumps({'редакция':'4.10.0-wip','записи':rows,'граница':'Покрытие переданных трёх наборов 4.9.0; не восстановление отсутствующего полного ZIP. Архивные .txt хранят исходные байты, а не выполняются.'},ensure_ascii=False,indent=2)+'\n')
print('Original subset records',len(rows),'archived changed',sum('4.9.0-различающиеся-байты' in r['путь_сохранённых_байтов'] for r in rows))
