from ops import *
import datetime,re
job='20260923-contextra-pr13-framefix-r01'
assert cmd(['git','-C',str(REPO),'rev-parse','HEAD']).strip()=='fe6e94c39f44388ce2c0bcfc262287f98cb309f6'
assert not cmd(['git','-C',str(REPO),'diff','--cached','--name-only']).strip()
paths=sorted(set(cmd(['git','-C',str(REPO),'diff','--name-only']).splitlines()+cmd(['git','-C',str(REPO),'ls-files','--others','--exclude-standard']).splitlines()))
assert len(paths)==7
cmd(['git','-C',str(REPO),'diff','--check'])
for p in paths:
    if not p.endswith('.md'):continue
    for target in re.findall(r'\]\(([^)]+)\)',(REPO/p).read_text()):
        if '://' in target or target.startswith('#'):continue
        assert ((REPO/p).parent/target.split('#')[0]).exists(),(p,target)
intent=json.loads((HERE/'build-intent.json').read_text())
for p,h in intent['hashes'].items():assert hashlib.sha256((REPO/p).read_bytes()).hexdigest()==h
save('verification.json',dict(cpu_tests=21,python='3.12',single_provider_frame_flow='PASS',
    single_provider_redis_reader='HELPER_FAILED; not rerun; mixed-provider reader verified',
    two_provider='PASS',three_provider='PASS',native_crash='FIXED',
    stop_reap='PASS',event_delivery='HTTP400 INVALID_PARAMS',web_browser='NOT_RUN',
    docs_links=True,whitespace=True,hashes={p:hashlib.sha256((REPO/p).read_bytes()).hexdigest() for p in paths}))
receipt=dict(schema_version='ltb1021.codex_hub.report_receipt.v1',receipt_id=job,
 timestamp=datetime.datetime.now(datetime.timezone(datetime.timedelta(hours=9))).isoformat(),
 session_alias='work-session',task='PR13 SDK Frame wrapper native crash 수정과 최소 GPU 재수용',
 results=['SDK iterator borrowed wrapper 보관2지점을 owned FrameEnvelope 즉시 복사로 수정',
  '파일1개 delta image; 단일/2/3-provider 처리 및 정상 Stop/reap 확인',
  'Gateway/WSS 복구와 사용자 metadata 시험 준비; 자연 Event 수신400은 후속'],
 verify=['Python3.12 표적21 PASS; 1 RTSP/1 decoder/3 provider 및 Redis Frame/PTS/objectRef 확인',
  '29채널stopped/모델4종ready/Artifact On HTTP On; 외부Start도 정상Stop 회수',
  '자연FALL4건 Artifact READY, HTTP400 INVALID_PARAMS; 과거 재전송 없음'],
 commits=[],remaining=['Event 수신 계약 HTTP400 원인 별도 확인','브라우저 수용/slow-branch GPU 지연 주입/다채널 미검증'])
save('report-receipt.json',receipt)
print(cmd(['codex-report-receipt','--profile','ltb1021','--session-alias','work-session','--receipt',str(HERE/'report-receipt.json')]))
out=Path('/tmp/codex/ltb1021/git-closeout')/job;out.mkdir(mode=0o700)
mf=out/'manifest.json'
args=['codex-git-closeout','prepare','--repository',str(REPO),'--output',str(mf),'--job-id',job,
 '--profile','ltb1021','--session-alias','work-session',
 '--title','fix(runtime): SDK Frame wrapper 수명 오류와 native crash 수정',
 '--message','Why=PR13 첫 Frame에서 iterator 종료 후 무효화된 SDK FrameMetadata를 읽어 채널 process가 segfault로 종료됐다.',
 '--message','What=SharedIngress/ProviderGate에서 borrowed wrapper 대신 순회 중 owned FrameEnvelope를 복사하고 수명/단일Frame 회귀 테스트와 운영 기록을 보완했다.',
 '--message','Impact=파일1개 delta Analytics image만 반영. 모델/threshold/SDK/Tracking 계약은 보존. Gateway/WSS 재개와 정상 Stop/reap 확인.',
 '--message','Verify=Python3.12 표적21 PASS. Pose/Fire 단독 및 2/3-provider Frame 처리, RTSP1/decoder1/branch3, Redis Frame/PTS와 Stop PASS. 단독단계 reader helper 실패는 mixed 단계에서 기존 ACL reader로 정정. 자연FALL4건 Artifact READY이나 HTTP400 INVALID_PARAMS 전송 미수용. 브라우저 NOT RUN.',
 '--message','Rollback=이전 image/전체Compose/private baseline 보존. 자동rollback/재Start 없음. 이전 PR13 image는 알려진 native crash가 있어 무검증 복귀하지 않는다.',
 '--message','Related=PR13-INTEGRATION-01; Event 수신400과 실제브라우저는후속',
 '--verify','Python3.12 21 targeted tests PASS; actual single/2/3-provider flow and Stop/reap PASS',
 '--verify','One RTSP socket/decoder thread, three provider threads; Redis reader Frame/PTS/objectRef checks; four models READY and WSS connected',
 '--verify','Natural FALL4 artifact READY / HTTP400 INVALID_PARAMS; no replay; browser/slow-branch fault injection NOT RUN; diff and doc links PASS',
 '--expires-in-seconds','86400']
for p in paths:args+=['--path',p]
print(cmd(args))
batch=out/'batch.json'
print(cmd(['codex-git-closeout','batch-prepare','--output',str(batch),'--batch-id',job,'--profile','ltb1021','--session-alias','work-session','--expected-group-count','1','--repository-label','contextra-analytics','--manifest',str(mf),'--expect-plan-hash',json.loads(mf.read_text())['plan_hash'],'--expires-in-seconds','86400']))
h=json.loads(batch.read_text())['plan_hash']
print(cmd(['codex-git-closeout','batch-plan','--batch-manifest',str(batch),'--expect-batch-plan-hash',h]))
print(cmd(['codex-git-closeout','batch-present','--batch-manifest',str(batch),'--expect-batch-plan-hash',h]))
