#!/usr/bin/env python3
import json,hashlib,sys,datetime,os
from pathlib import Path
PROJECT='gacmai_20260718_091744';ROOT=Path('/data/video-pipeline/GacMaiAudio/project')/PROJECT;A=ROOT/'artifacts'
def sha(p):return hashlib.sha256(Path(p).read_bytes()).hexdigest()
def atomic(p,d):
 t=p.with_suffix(p.suffix+'.tmp');t.write_text(json.dumps(d,ensure_ascii=False,indent=2)+'\n');os.replace(t,p)
def main():
 if len(sys.argv)!=4:raise SystemExit('usage: promote_story.py STORY VALIDATION AUDIT')
 sp,vp,ap=map(Path,sys.argv[1:]);s=json.loads(sp.read_text());v=json.loads(vp.read_text());a=json.loads(ap.read_text());sh=sha(sp);outline=A/'outline_selected.json';assert outline.exists();oh=sha(outline)
 assert s['project_id']==PROJECT and s['source_outline_sha256']==oh
 assert v.get('status')=='passed' and v.get('source_sha256')==sh and v.get('outline_sha256')==oh and v.get('parts')==12 and v.get('paragraphs')==144 and 14000<=v.get('word_count',0)<=15000 and v.get('errors')==[]
 assert a.get('verdict')=='pass' and a.get('story_sha256')==sh and a.get('all_144_read') is True and a.get('blocking_findings')==[]
 dst=A/'story_canonical.json';assert not dst.exists();dst.write_bytes(sp.read_bytes());assert sha(dst)==sh;now=datetime.datetime.now(datetime.timezone.utc).isoformat()
 release={'status':'passed','project_id':PROJECT,'outline_sha256':oh,'story_sha256':sh,'validation_sha256':sha(vp),'audit_sha256':sha(ap),'parts':12,'paragraphs':144,'word_count':v['word_count'],'released_at':now};atomic(A/'story_release_receipt.json',release)
 auth={'status':'passed','project_id':PROJECT,'story_sha256':sh,'story_audit_sha256':sha(ap),'tts_authorized':True,'visual_contract_authorized':True,'render_authorized':False,'publish_authorized':False,'authorized_at':now};atomic(A/'production_authorization.json',auth)
 for fn in ('project.json','status.json'):
  p=ROOT/fn;d=json.loads(p.read_text());d.update({'stage':'tts_projection','canonical_story_sha256':sh,'story_locked':False,'tts_locked':False,'visual_spend_locked':True,'render_locked':True,'publish_locked':True,'updated_at':now});atomic(p,d)
 print(json.dumps({'status':'released','story_sha256':sh,'audit_sha256':sha(ap),'word_count':v['word_count'],'tts_authorized':True}))
if __name__=='__main__':main()
