"""컷·연결·새 버전 미디어와 실제 실행 증거를 검사한다.""" import hashlib import json from pathlib import Path import jsonschema ROOT=Path(__file__).resolve().parents[3] PROJECT=ROOT/'projects/water-hydrogen-bond-surface-tension' def read(path): return json.loads(path.read_text(encoding='utf-8')) if __name__=='__main__': a=read(PROJECT/'stages/08-scenes/r3/artifact.json') b=read(PROJECT/'stages/09-entities/r3/artifact.json') schema=read(ROOT/'contracts/artifact.schema.json') jsonschema.validate(a,schema) jsonschema.validate(b,schema) assert a["revision"]==b["revision"]==3 assert {"stage_id":"08-scenes","revision":3} in b["inputs"] cuts=read(PROJECT/'stages/07-cuts/r1/artifact.json')['payload'] ids=[c['id'] for c in cuts['cuts']] assert len(ids)==31 and len(cuts['captions'])==38 and cuts['narration_duration_ms']==110560 assert cuts['cuts'][0]['start_ms']==0 and cuts['cuts'][-1]['end_ms']==110560 assert all(0=.03 and containment['minimum_projected_margin_px']>0 samples=preview['samples'] assert len(samples)==6 and len({s['id'] for s in samples})==6 assets=[dict(path=source['path'],sha256=source['sha256'])] frame_reviews=[] for sample in samples: media=sample['media'] path=ROOT/media['path'] assert path.is_relative_to(PROJECT/'stages/08-scenes/r3') and media['verified'] evidence_path=path.parent/'evidence.json' evidence=read(evidence_path) assert evidence['media']==media and evidence['scene_file']==source and evidence['render_profile']==preview['render_profile'] assert (media['width'],media['height'])==(1080,1920) if media['kind']=='video': cut=next(c for c in cuts['cuts'] if c['id']==sample['cut_ids'][0]) assert media['duration_ms']==cut['end_ms']-cut['start_ms'] assert evidence['logical_frames']==list(range(cut['start_ms']//20,cut['end_ms']//20)) for frame in (evidence['logical_frames'][0],evidence['logical_frames'][len(evidence['logical_frames'])//2],evidence['logical_frames'][-1]): f=path.parent/f'frame-{frame:08}.png' frame_reviews.append(f.relative_to(ROOT).as_posix()) assets.append(dict(path=f.relative_to(ROOT).as_posix(),sha256=hashlib.sha256(f.read_bytes()).hexdigest())) for f in (path,evidence_path): assets.append(dict(path=f.relative_to(ROOT).as_posix(),sha256=hashlib.sha256(f.read_bytes()).hexdigest())) result=dict(result='GREEN',cuts=31,captions=38,connections=30,total_ms=110560,fps=50,total_frames=5528,profile=preview['render_profile'],source_sha256=source['sha256'],samples=6,visual_review_frames=frame_reviews,actual_assets=assets,scenes_approval='pending',formal_10_12='not_started') motion=read(PROJECT/'stages/08-scenes/r3/motion-check.json') assert motion['source_sha256']==source['sha256'] and len(motion['views'])==3 for view in motion['views']: assert all(change>0 for change in view['mean_absolute_pixel_change']) path=ROOT/view['mobile_view_path'] assert hashlib.sha256(path.read_bytes()).hexdigest()==view['mobile_view_sha256'] assets.append(dict(path=view['mobile_view_path'],sha256=view['mobile_view_sha256'])) (PROJECT/'stages/08-scenes/r3/design-check.json').write_text(json.dumps(result,ensure_ascii=False,indent=2)+'\n',encoding='utf-8') print('DESIGN_GREEN: 31 cuts, 30 boundaries, 38 captions, 6 actual samples')