#!/usr/bin/env python3
import json,hashlib,sys
from pathlib import Path
PROJECT='gacmai_20260718_075153'
CONCEPT_SHA='0ac2600ec1e964494a688426ed3f59e1bd0d46d4f34982756cfb539a29bed7a0'
CAST=['Võ Thanh Hà','Nguyễn Hữu Duy','Trần Mộc Lan','Lê Quang Vinh','Phạm Ngọc Thư','Đỗ Minh Khang']
def sha(p):return hashlib.sha256(p.read_bytes()).hexdigest()
def main():
 if len(sys.argv)!=4:raise SystemExit('usage: build_writer_bundles.py OUTLINE OUTPUT_DIR EXPECTED_OUTLINE_SHA')
 src=Path(sys.argv[1]);out=Path(sys.argv[2]);outline_sha=sys.argv[3];d=json.loads(src.read_text());assert sha(src)==outline_sha and d['source_concept_sha256']==CONCEPT_SHA
 out.mkdir(parents=True,exist_ok=True);rows=[]
 for start in (1,5,9):
  end=start+3;parts=[x for x in d['parts'] if start<=int(x['part_number'])<=end];assert len(parts)==4
  bundle={'schema_version':1,'task':'write_story_batch','project_id':PROJECT,'source_outline_sha256':outline_sha,'source_concept_sha256':CONCEPT_SHA,'part_range':[start,end],'contract':{'language':'natural Vietnamese literary audio prose','paragraphs':'exactly 12 paragraphs per part, one per beat, in beat order','target_words':sum(b['target_words'] for p in parts for b in p['beats']),'pov':'close third-person limited only to Võ Thanh Hà; no first-person narrator and no other interiority','exact_named_cast':CAST,'forbidden':['extra named people','scaffold labels or beat IDs in prose','checklist narration','repeated template sentences','supernatural/medical/petroleum/radio/tape/song domains','operational wrongdoing instructions'],'evidence':'weave source/custody/authority/limits naturally into scenes; do not recite all four mechanically','consent_privacy':'render actual choices and consequences; no universal disclaimer repeated across paragraphs','audio':'complete grammatical sentences, pronounceable prose, varied cadence, no placeholders or notes to editor'},'parts':parts}
  p=out/f'writer_bundle_{start}_{end}.json';p.write_text(json.dumps(bundle,ensure_ascii=False,indent=2)+'\n');rows.append({'range':[start,end],'path':str(p),'sha256':sha(p),'target_words':bundle['contract']['target_words']})
 print(json.dumps({'status':'passed','outline_sha256':outline_sha,'bundles':rows},ensure_ascii=False,indent=2))
if __name__=='__main__':main()
