import json,subprocess,datetime,os
from pathlib import Path
os.umask(0o077)
repo=Path('/workspace/contextra-analytics-runtime-lifecycle-refactor');here=Path(__file__).parent
def cmd(a):return subprocess.check_output(a,text=True,timeout=60)
job='20260921-icerti-login-guide-r01'
assert not cmd(['git','-C',str(repo),'diff','--cached','--name-only']).strip()
paths=cmd(['git','-C',str(repo),'diff','--name-only']).splitlines()+cmd(['git','-C',str(repo),'ls-files','--others','--exclude-standard']).splitlines()
assert len(paths)==5
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='현장 관제 재로그인과 수동 실행 가이드',
 results=['기존계정거부후사용자승인새비밀번호1회로그인성공/TLS/세션저장',
 'private비밀번호와session identity정합확인/Sidecar정상기동',
 '사람용가이드와1회로그인/기존세션복원도구준비'],
 verify=['기존값401실패/변경되지않은세션복원확인','새값로그인PASS/ready200/auth=null',
 'WSS90초내미연결. helper회수/도구문법과세션backup선택검증PASS'],commits=[],remaining=['관제측WSS재연결확인'])
rp=here/'report-receipt.json';rp.write_text(json.dumps(receipt,ensure_ascii=False,indent=2))
print(cmd(['codex-report-receipt','--profile','ltb1021','--session-alias','work-session','--receipt',str(rp)]))
out=Path('/tmp/codex/ltb1021/git-closeout')/job;out.mkdir(mode=0o700);mf=out/'manifest.json'
a=['codex-git-closeout','prepare','--repository',str(repo),'--output',str(mf),'--job-id',job,'--profile','ltb1021','--session-alias','work-session',
 '--title','ops(auth): 현장 재로그인 절차와 수동 가이드 준비',
 '--message','Why=계정변경뒤현장AI로그인을복구하고비밀값노출없이사람이동일절차를수행하도록한다.',
 '--message','What=공식Auth를사용하는1회로그인및기존세션복원도구,성공/401/WSS대기구분가이드와Owner기록을추가했다.',
 '--message','Impact=인증Sidecar만정지/기동. 성공후현장private인증값/세션정합화. 비밀값은Git에없고Analytics/카메라/test서비스변경없음.',
 '--message','Verify=기존계정401과기존세션복원,사용자승인새값로그인1회PASS/TLS/session/ready200확인. WSS90초미연결. 도구문법/세션backup선택검증PASS.',
 '--message','Rollback=인증값과세션은짝으로관리하며관제에서폐기된token을무조건복구하지않는다. 실패후반복로그인금지. 이전비밀값/세션은현장private백업만사용한다.',
 '--verify','Login PASS and session/config identity matched; auth ready200; WSS NOT CONFIRMED',
 '--verify','401/old-session restoration executed; no remaining helper; syntax/backup selection PASS','--expires-in-seconds','86400']
for p in paths:a+=['--path',p]
print(cmd(a));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]))
