import importlib.util,json,os,pathlib,subprocess,shutil,urllib.request
os.umask(0o077)
spec=importlib.util.spec_from_file_location('previous_gate','/tmp/codex/ltb1021/2026-09-11_service-stop_r01/gate.py')
g=importlib.util.module_from_spec(spec);spec.loader.exec_module(g)
R=pathlib.Path(__file__).parent
def gate():
 assert not (R/'gate.json').exists()
 assert g.sh(['git','-C',str(g.REPO),'rev-parse','HEAD']).strip()=='4bdf50cf2013f1a2f6e9fe85cbb1ec0634b4efa4'
 assert not g.sh(['git','-C',str(g.REPO),'status','--porcelain']).strip()
 c=g.inspect();e=g.load_env_file(str(g.ENV))
 assert c['Image']=='sha256:0a40a255bfdf0594c4fd2599a982c8576247713cd7ca168e86b908bc37b92aee'
 assert c['State']['Status']=='running' and c['State']['Health']['Status']=='healthy'
 assert c['RestartCount']==0 and not c['State']['OOMKilled']
 assert c['HostConfig']['RestartPolicy']=={'Name':'on-failure','MaximumRetryCount':3}
 overlay=pathlib.Path(e['CONTEXTRA_RUNTIME_STATE_ROOT'])/'streams_runtime.yaml'
 rows=g.yaml.safe_load(overlay.read_text())['added'];assert len(rows)==1
 s=rows[0];assert all(s[x] is False for x in ['store','active_learning','autostart']) and s['scenarios']=='off'
 assert s['inference_profile']['roles']==['det'] and s['inference_profile']['det_model']=='RFDETRMedium'
 opener=urllib.request.build_opener(urllib.request.ProxyHandler({}))
 with opener.open('http://127.0.0.1:'+e['FASTAPI_HOST_PORT']+'/api/v1/streams',timeout=4) as f:rows=json.load(f)['streams']
 assert len(rows)==1 and rows[0]['state']=='stopped'
 assert g.sha(g.CFG)=='5e5a4d22786f8b5218ac821379fbec091d9e3006f62c880ee3e3da5ced2f0e0b'
 assert g.sha(g.CFG.parent/'2/model.plan')=='5fdf1e9c55ab947a3b7d5f7f6bdceaf1e36a9e52efdf86f5a15d3b99b8631d1e'
 root=g.sh(['docker','info','--format','{{.DockerRootDir}}']).strip();free=shutil.disk_usage(root).free
 assert free>=15*1024**3
 assert subprocess.run(['pgrep','-f',r'(^|/)docker (build|buildx build|pull)'],capture_output=True).returncode==1
 mem={l.split(':')[0]:int(l.split()[1]) for l in pathlib.Path('/proc/meminfo').read_text().splitlines()}
 assert mem['MemAvailable']>6*1024**2 and g.gpu()<16384
 identity=pathlib.Path(e['CONTEXTRA_RUNTIME_STATE_ROOT'])/'installation_identity.json'
 out=dict(container_id=c['Id'],old_image=c['Image'],old_tag=e['CONTEXTRA_IMAGE'],env_hash=g.sha(g.ENV),
 config_hash=g.sha(g.CFG),plan_hash=g.sha(g.CFG.parent/'2/model.plan'),overlay_hash=g.sha(overlay),
 original_restart=c['HostConfig']['RestartPolicy'],other_containers=g.others(),gpu_mib=g.gpu(),
 disk_free=free,docker_root=root,identity_exists=identity.exists(),
 identity_hash=g.sha(identity) if identity.exists() else None,
 existing_spec_identity=bool(s.get('server_id') and s.get('source_id')))
 (R/'gate.json').write_text(json.dumps(out,indent=2))
 print(json.dumps({k:out[k] for k in ['old_image','gpu_mib','disk_free','identity_exists','existing_spec_identity']}))
if __name__=='__main__':gate()
