import csv
from datetime import datetime, timezone, timedelta
import json
import subprocess

from run import R, REPO, FILES, p

job='contextra-medium-saturation-20260916'
doc='docs/profiles/ltb1021/topics/runtime-lifecycle/runs/20260916T142725+0900-run-medium-saturation.md'
owner='docs/profiles/ltb1021/topics/runtime-lifecycle/README.ko.md'
rows=[]
for label in ('initial','deterioration'):
    rows += p.read(label+'-summary.json')['rows']
with (R/'summary.csv').open('w') as f:
    writer=csv.DictWriter(f,fieldnames=list(rows[0]));writer.writeheader();writer.writerows(rows)
final=p.read('final.json'); image=p.read('image.json')
assert final['success'] is False and final['diagnostics_off']
assert all(p.sha(REPO/n)==v for n,v in image['hashes'].items())
assert p.read('saturation-source2.json')['success'] and p.read('saturation-image.json')['success']
p.save('completion.json',dict(at=datetime.now(timezone(timedelta(hours=9))).isoformat(),
    runtime='BELOW_TARGET_RESTORED',candidate_image=image['tag'],current_image=final['image'],
    source_tests=18,image_tests=18,first_source_tests=dict(tests=26,errors=1,reason='Pre-existing identity test expects metadata on skipped duplicate PTS Frame'),
    post_saturation_seconds=11.30956180789508,post_saturation_target_completed=False,
    portfolio='LOW: bounded diagnostics and unresolved analysis; no portfolio milestone',
    next='Per-channel child process implementation; retain control API and shared Triton; no further same-process exploration'))
p.save('receipt.json',dict(schema_version='ltb1021.codex_hub.report_receipt.v1',receipt_id=job,
    timestamp=datetime.now(timezone(timedelta(hours=9))).isoformat(),session_alias='work-session',
    task='Contextra 새 image Medium3 collector 포화 최종확인과 구조전환 재개점',
    results=['기본Off·60초 bounded collector/결과 worker wall·thread CPU 계측 추가',
             '초기 각약10FPS, 실제collector1000개 이후7.07~7.69FPS·stale22~28 재현으로 중단',
             '기존image/config·원래3채널running 복원, 추가탐색없이 채널별process분리 후속 확정'],
    verify=['source/image 각18 targeted tests PASS; 최초확장검증의기존identity불일치1건별도보존',
            '포화후30초목표미완료·11.31초중단,collector bounded1000 유지',
            'sender/Redis/identity/Anchor/모델설정보존·계측Off·helper종료·복원후queue0/stale0'],
    commits=[],remaining=['API/공유Triton 유지한 채널별child process 구현',
                         'GIL/특정lock 원인미확정,Pose/Tracking/16채널/Web성공미주장',
                         '사용자GitCloseout실행대기']))
subprocess.run(['codex-report-receipt','--profile','ltb1021','--session-alias','work-session',
                '--receipt',str(R/'receipt.json')],check=True,timeout=30)

def command(args):
    return subprocess.check_output(args,cwd=REPO,text=True,timeout=40)

paths=sorted(FILES+[doc,owner])
assert not command(['git','diff','--cached','--name-only']).strip()
actual=set(command(['git','diff','--name-only']).splitlines()+command(['git','ls-files','--others','--exclude-standard']).splitlines())
assert actual==set(paths),actual-set(paths)
command(['git','diff','--check'])
args=['codex-git-closeout','prepare','--repository',str(REPO),'--output',str(R/'manifest.json'),
      '--job-id',job,'--profile','ltb1021','--session-alias','work-session',
      '--title','test(runtime): Medium 포화 계측과 프로세스 분리 재개점 기록',
      '--message','Why=초기 정상 이후 결과 처리 저하를 마지막 제한시험으로 판별한다.',
      '--message','What=collector 개수와 잠금/제거·결과 wall/thread CPU를 bounded 계측하고 실제 포화 전후를 비교했다.',
      '--message','Impact=포화후 결과7.07~7.69FPS로 저하해 기존 image/config와 Medium3 running으로 복원했다. 성능수정은 없고 다음은 채널별process분리다.',
      '--message','Verify=source/image 각18tests PASS. 초기21.93초 정상,포화후11.31초 악화로30초목표 중단. 기존identity테스트1불일치별도보존. sender/Redis보존·계측Off·diff-check PASS.',
      '--message','Rollback=runtime은 이미 기존image/Compose/env로복원. source는이번진단추가 exact diff만되돌릴수있고 원장/모델/원본은보존한다.',
      '--verify','18 targeted tests each source/image PASS; actual collector1000 and deterioration observed; original runtime restored; git diff --check PASS.']
for path in paths:
    args+=['--path',path]
print(command(args))
manifest=p.read('manifest.json')
print(command(['codex-git-closeout','batch-prepare','--output',str(R/'batch.json'),'--batch-id',job,
    '--profile','ltb1021','--session-alias','work-session','--expected-group-count','1','--repository-label','contextra-analytics',
    '--manifest',str(R/'manifest.json'),'--expect-plan-hash',manifest['plan_hash']]))
batch=p.read('batch.json')
print(command(['codex-git-closeout','batch-plan','--batch-manifest',str(R/'batch.json'),'--expect-batch-plan-hash',batch['plan_hash']]))
print(command(['codex-git-closeout','batch-present','--batch-manifest',str(R/'batch.json'),'--expect-batch-plan-hash',batch['plan_hash']]))
