#!/usr/bin/env python3
from pathlib import Path
import hashlib,json,datetime,shutil
P='gacmai_20260717_104203';R=Path('/data/video-pipeline/GacMaiAudio/project')/P;A=R/'artifacts'
def sha(p):return hashlib.sha256(p.read_bytes()).hexdigest()
def load(name):
 p=A/name
 if not p.exists():raise SystemExit(f'missing {name}')
 return p,json.loads(p.read_text())
story,sd=load('story_package_candidate.json');story_sha=sha(story)
det,dd=load('deterministic_story_receipt.json');val,vd=load('story_validation.json');dup,dupd=load('duplication_audit.json');ev,ed=load('evidence_authority_audit.json');audit,ad=load('full_story_release_audit.json')
if any(x.get('status')!='passed' for x in (dd,vd,dupd,ed)):raise SystemExit('deterministic gate not passed')
if dupd.get('violation_count') not in (0,None):raise SystemExit('duplication not zero')
if ad.get('verdict')!='pass' or ad.get('source_modified') is not False:raise SystemExit('editorial release gate not pass')
for name,x in [('deterministic',dd),('validation',vd),('duplication',dupd),('evidence',ed),('editorial',ad)]:
 vals=[x.get(k) for k in ('story_sha256','expected_sha256','before_sha256','after_sha256','source_sha256')]
 if story_sha not in vals:raise SystemExit(f'{name} not bound to story SHA')
canonical=A/'story_package_canonical.json'
if canonical.exists():raise SystemExit('canonical story already exists; refusing overwrite')
shutil.copyfile(story,canonical)
now=datetime.datetime.now(datetime.timezone.utc).isoformat();release={'status':'passed','project_id':P,'story_sha256':story_sha,'canonical_story_path':str(canonical),'deterministic_receipt_sha256':sha(det),'validation_sha256':sha(val),'duplication_sha256':sha(dup),'evidence_authority_sha256':sha(ev),'editorial_audit_sha256':sha(audit),'tts_authorized':True,'cx_authorized':True,'released_at':now};(A/'story_release_manifest.json').write_text(json.dumps(release,ensure_ascii=False,indent=2)+'\n')
status=json.loads((R/'status.json').read_text());status.update({'stage':'production','story_sha256':story_sha,'story_release_verdict':'pass','tts_authorized':True,'cx_authorized':True,'provider_spend_authorized':True,'updated_at':now});(R/'status.json').write_text(json.dumps(status,ensure_ascii=False,indent=2)+'\n');print(json.dumps(release,ensure_ascii=False))
