#!/usr/bin/env python3
import hashlib,json,stat
from pathlib import Path
HERE=Path(__file__).resolve().parent
files=[];dirs=[]
for p in sorted(HERE.rglob('*')):
    if p.name=='manifest20.json' or '__pycache__' in p.parts:continue
    if p.is_symlink():raise RuntimeError('No links in seal: '+str(p))
    mode=stat.S_IMODE(p.stat().st_mode)
    if p.is_dir():
        if 'private' in p.relative_to(HERE).parts and mode!=0o700:raise RuntimeError('Private directory mode')
        dirs.append({'path':p.relative_to(HERE).as_posix(),'mode':oct(mode)})
    elif p.is_file():
        private='private' in p.relative_to(HERE).parts
        if private and mode!=0o600:raise RuntimeError('Private file mode: '+str(p))
        data=p.read_bytes();files.append({'path':p.relative_to(HERE).as_posix(),'private':private,'bytes':len(data),'sha256':hashlib.sha256(data).hexdigest(),'mode':oct(mode)})
body={'task':'ZHCTPROMPT-20260928-SMART-CANTEEN-DUAL-DB-COMPAT-PLAN','slice':'remaining20','HTTP':50,'actual_log_rows_per_lane':97,'files':files,'directories':dirs,'first4_seal_unchanged':'9f5b90ed39817a5afc92cde54607eac7fcb97359cedc61d924cb9e495912581e'}
body['seal_sha256']=hashlib.sha256(json.dumps(body,sort_keys=True,separators=(',',':')).encode()).hexdigest()
(HERE/'manifest20.json').write_text(json.dumps(body,ensure_ascii=False,indent=2)+'\n')
print(json.dumps({'seal_sha256':body['seal_sha256'],'public_files':sum(not f['private'] for f in files),'private_files':sum(f['private'] for f in files)}))
