import datetime
import json
import os
from pathlib import Path
import subprocess

os.umask(0o077)
repo = Path('/workspace/contextra-analytics-runtime-lifecycle-refactor')
here = Path(__file__).parent
job = '20260920-contextra-fall-skip-hold-r01'
out = Path('/tmp/codex/ltb1021/git-closeout')/job
out.mkdir(mode=0o700)

def cmd(args):
    p = subprocess.run(args, capture_output=True, text=True, timeout=90)
    assert p.returncode == 0, p.stdout+p.stderr
    return p.stdout

paths = ['app/fall_config.py', 'app/fall_scenario.py', 'tests/test_fall_skip_hold.py',
         'docs/scenarios/SCENARIO_WEB_READY.ko.md',
         'docs/profiles/ltb1021/topics/runtime-lifecycle/README.ko.md',
         'docs/profiles/ltb1021/topics/runtime-lifecycle/runs/20260920T214915+0900-run-fall-skip-hold.md']
assert not cmd(['git','-C',str(repo),'diff','--cached','--name-only']).strip()
changed = set(cmd(['git','-C',str(repo),'diff','--name-only']).splitlines()+
              cmd(['git','-C',str(repo),'ls-files','--others','--exclude-standard']).splitlines())
assert changed == set(paths)
cmd(['git','-C',str(repo),'diff','--check'])
receipt = {'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':'FALL 임시 DOWN 대기 생략 옵션과 3번 시험 준비',
 'results':['기본 Off 내부 옵션 추가, 선행 낙상 조건과 episode 보호 유지',
            'Analytics만 반영, 3번 옵션 On/score0.30 저장 및 22채널 stopped'],
 'verify':['Python3.12 옵션9+기존 연결11 총20 PASS; 초기 fixture 교정 후 최종 실행',
           'Pose READY/WSS/Artifact On, 실행 source hash2 일치, 비대상 컨테이너/기존 원장 보존'],
 'commits':[], 'remaining':['사용자 수동 Start와 Event 연결 시험 대기',
                           '시험 종료 피드백 후 옵션 Off RESET; 정확도 미검증'],
 }
rp=here/'report-receipt.json'
with rp.open('x') as f: json.dump(receipt,f,ensure_ascii=False,indent=2)
print(cmd(['codex-report-receipt','--profile','ltb1021','--session-alias','work-session','--receipt',str(rp)]))
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','feat(fall): DOWN 대기 생략 임시 시험 옵션 추가',
 '--message','Why=검출 이후 DOWN 후보가 확정으로 이어지지 않는 상황에서 Event 연결만 분리 시험한다.',
 '--message','What=기본 Off test_skip_down_hold와 현재 Frame 즉시 확정, 표적 테스트 및 원복 가이드를 추가했다.',
 '--message','Impact=선행 arming/transition/ROI/score와 episode 보호는 유지한다. Analytics만 교체하고 3번 옵션 On, score0.30 및 전체22채널 stopped로 대기한다.',
 '--message','Verify=Python3.12 표적20 PASS. 실행 source hash2, Pose READY, WSS 연결, Artifact On/HTTP On, 기존 원장 및 비대상 컨테이너 보존. 실제 Event 시험과 정확도는 미검증.',
 '--message','Rollback=시험 종료 피드백 후 3번 stopped 상태에서 Settings/CAS로 옵션 false. 기존 image/env 보존, 자동 rollback 및 재Start 없음.',
 '--message','Related=FALL-WIRE-01; 임시 시험 옵션 RETAIN, 종료 후 RESET',
 '--verify','Python3.12 targeted 20 PASS; source hashes2 match; default false',
 '--verify','Pose READY, WSS connected, Artifact On/HTTP On, 22 stopped; ledger/non-targets preserved',
 '--verify','git diff --check PASS; actual scenario test NOT RUN', '--expires-in-seconds','86400']
for path in paths: args+=['--path',path]
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]))
