#!/usr/bin/env python3
from pathlib import Path
import hashlib,json,os
ROOT=Path('/data/video-pipeline/HaTramAudio/project/015-Buc-Tranh-Khong-Co-Chu-Ky')
PROJECT_ID=ROOT.name;RUN_ID='run-20260720T181013Z-3b1f33ef';OWNER='Levy';TITLE='Bức Tranh Không Có Chữ Ký';WORK=ROOT/'work/artwork'/RUN_ID
def sha(p):
 h=hashlib.sha256()
 with p.open('rb') as f:
  for b in iter(lambda:f.read(8*1024*1024),b''):h.update(b)
 return h.hexdigest()
def guard():
 d=json.loads((ROOT/'.ownership-lock.json').read_text())
 assert d['project_id']==PROJECT_ID and d['run_id']==RUN_ID and d['owner']==OWNER
def main():
 guard();authority={k:ROOT/k for k in ['story/story-canon.txt','script/story-brief.json','script/identity-registry.json','script/reveal-ledger.json','script/outline.json','script/promotion-report.json']};assert all(p.is_file() for p in authority.values())
 promo=json.loads(authority['script/promotion-report.json'].read_text());canon=sha(authority['story/story-canon.txt']);assert promo['verified'] and promo['canon_sha256']==canon
 identity=json.loads(authority['script/identity-registry.json'].read_text())
 shared=f'''IDENTITY REGISTRY NỘI BỘ, chỉ để giữ nhất quán nhân vật, tuyệt đối không render thành chữ:\n{json.dumps(identity,ensure_ascii=False)}\n\nTên chính thức: "{TITLE}". Thể loại: ngôn tình đô thị trưởng thành, bí ẩn nghệ thuật, chữa lành. Bối cảnh công khai: phòng giám định tranh cao cấp trong thành phố hư cấu Trung Quốc, mưa trên mái kính, bàn thao tác bảo tồn, ánh tungsten hổ phách đối lập xanh xám mưa. Trần Nghi Lan là nữ chuyên viên phục chế tranh trưởng thành, người châu Á hư cấu, tóc đen ngang vai buộc thấp, áo blouse bảo tồn màu ngà trên sơ mi xanh nhạt, găng tay nitrile, ánh mắt bình tĩnh nhưng quyết liệt. Lục Cảnh Hoài là nam luật sư quản lý di sản trưởng thành, người châu Á hư cấu, tóc đen gọn, suit xanh than không cà vạt, cầm cặp hồ sơ trơn. Motif công khai: một bức tranh chân dung vô danh, lớp sơn đỏ rượu vang che dấu kho trừu tượng, đèn kiểm tra xiên và phong bì niêm phong trơn. Giới hạn tiết lộ: không thể hiện nội dung phụ lục di chúc, danh tính người ra lệnh che phủ, kết luận pháp lý, kết cục nghề nghiệp hoặc kết cục tình cảm.\n\nPhong cách key art phim điện ảnh cao cấp, digital illustration bán hiện thực, tối giản, một focal point rõ, low-key lighting, tương phản mạnh có kiểm soát, depth foreground-midground-background, không collage, không card, không slide, không mockup, không mô phỏng người thật.\n\nMọi khung tranh, hồ sơ, phong bì, tem niêm phong, màn hình và nhãn trong cảnh phải trơn hoặc chỉ có đường nét không tạo ký tự đọc được. Không logo, watermark, chữ ký, số, pseudo-text hoặc chữ môi trường ngoài các khối chữ bắt buộc. Provider tạo hoàn chỉnh hình và typography trong cùng raster; cấm background no-text, text layer riêng hoặc chừa chỗ hậu kỳ.\n'''
 poster=shared+f'''\nTạo poster ngang tỷ lệ 16:9, master 1920x1080 cho intro/thumbnail. Nghi Lan là focal point bên bàn giám định, nâng đèn kiểm tra trên bức chân dung vô danh có lớp đỏ rượu vang; Cảnh Hoài đứng lớp sau cạnh tủ kính và mái kính mưa. Phong bì trơn ở foreground. Không lộ twist. Provider tự quyết font, vị trí, kích thước, xuống dòng, khoảng cách và phân cấp.\n\nRENDER CHÍNH XÁC BA KHỐI CHỮ TIẾNG VIỆT SAU TRỰC TIẾP TRONG CÙNG ẢNH, KHÔNG THÊM CHỮ KHÁC:\n"Hạ Trâm Audio"\n"{TITLE}"\n"Truyện được phát độc quyền tại Hạ Trâm Audio, nghiêm cấm sao chép dưới mọi hình thức"\n\nGiữ nguyên từng chữ, dấu tiếng Việt và dấu phẩy; chữ dễ đọc, không cắt hoặc che.\n'''
 right=shared+f'''\nTạo key art dọc tỷ lệ chính xác 656:1080, master 1080x1778 dùng nguyên raster làm panel phải. Nghi Lan là focal point cạnh bức chân dung vô danh và ánh đèn kiểm tra xiên; Cảnh Hoài lùi ở lớp sau cạnh mái kính mưa. Bố cục dọc tối giản, không crop chủ thể quan trọng. Provider tự quyết toàn bộ typography.\n\nRENDER CHÍNH XÁC BA KHỐI CHỮ TIẾNG VIỆT SAU TRỰC TIẾP TRONG CÙNG ẢNH, KHÔNG THÊM CHỮ KHÁC:\n"Hạ Trâm Audio"\n"{TITLE}"\n"Truyện được phát độc quyền tại Hạ Trâm Audio, nghiêm cấm sao chép dưới mọi hình thức"\n\nGiữ nguyên từng chữ, dấu tiếng Việt và dấu phẩy; chữ dễ đọc, không cắt hoặc che.\n'''
 left=shared+f'''\nTạo branding panel điện ảnh dọc tỷ lệ chính xác 656:1080, master 1080x1778 cho cạnh trái layout. Cùng color grade với poster: chi tiết bàn giám định trừu tượng, vệt sơn đỏ rượu vang, kính mưa và ánh đèn tungsten; không nhân vật, không tên truyện, không dòng độc quyền. Cạnh phải có transition texture nhẹ, không aperture/khung màn hình/layout giả. Provider tự quyết typography.\n\nRENDER CHÍNH XÁC HAI KHỐI CHỮ TIẾNG VIỆT SAU TRỰC TIẾP TRONG CÙNG ẢNH, KHÔNG THÊM CHỮ KHÁC:\n"Hạ Trâm Audio"\n"Like • Chia sẻ • Đăng ký"\n\nGiữ nguyên chính tả và dấu tiếng Việt; chữ dễ đọc, không cắt hoặc che.\n'''
 WORK.mkdir(parents=True,exist_ok=True);items={}
 for key,prompt in {'intro_poster':poster,'right_panel':right,'left_panel':left}.items():
  p=WORK/f'{key}.prompt.txt';p.write_text(prompt);items[key]={'prompt_path':str(p),'prompt_sha256':sha(p)}
 manifest={'schema_version':1,'project_id':PROJECT_ID,'run_id':RUN_ID,'status':'locked','verified':True,'source_canon_sha256':canon,'authority_sha256':{k:sha(p) for k,p in authority.items()},'canonical_title':TITLE,'provider_skill':'tao-anh','provider_model':'cx/gpt-5.5-image','provider_only_typography':True,'text_postprocessing_allowed':False,'items':items}
 p=ROOT/'script/image-prompts.json';tmp=p.with_name('.image-prompts.json.tmp');tmp.write_text(json.dumps(manifest,ensure_ascii=False,indent=2)+'\n');os.replace(tmp,p);print(json.dumps(manifest,ensure_ascii=False))
if __name__=='__main__':main()
