#!/usr/bin/env python3
from __future__ import annotations
import hashlib,importlib.util,json,stat,subprocess,sys
from pathlib import Path
ROOT=Path(__file__).resolve().parent
PROJECT=ROOT.parents[3]
PROFILE=Path('/home/cube/.hermes/profiles/dualcoachtest')
def sha(p:Path)->str:return hashlib.sha256(p.read_bytes()).hexdigest()
def main()->int:
 seal=json.loads((ROOT/'READINESS-SEAL-v3.json').read_text());manifest=json.loads((ROOT/'candidate-manifest.json').read_text());rows=json.loads((ROOT/'PACKAGE-INVENTORY-v3.json').read_text());checks=0
 def need(ok:bool,msg:str)->None:
  nonlocal checks
  if not ok:raise RuntimeError(msg)
  checks+=1
 need(seal['status']=='READY_STRICT_REHEARSAL','status');need(seal['full_candidate_digest']==manifest['full_candidate_digest'],'candidate');need(sha(ROOT/'PACKAGE-INVENTORY-v3.json')==seal['package_inventory_sha256'],'package root')
 expected={x['path'] for x in rows};allowed={'PACKAGE-INVENTORY-v3.json','CANDIDATE-SEAL-v3.json','READINESS-SEAL-v3.json','LAUNCH-CONTROLLER-SEAL-v7.json','PERMISSION-v7.json','launch_controller_v7.py','verify_successor_v3.py'};actual={p.relative_to(ROOT).as_posix() for p in ROOT.rglob('*') if p.is_file() and '__pycache__' not in p.parts and '.pytest_cache' not in p.parts};need(actual==expected|allowed,'unindexed package bytes')
 for row in rows:
  p=ROOT/row['path'];need(p.is_file() and p.stat().st_size==row['size'] and sha(p)==row['sha256'],row['path'])
 need(sha(ROOT/'CANDIDATE-SEAL-v3.json')==seal['candidate_seal_v3_sha256'],'candidate seal');need(sha(ROOT/'LAUNCH-CONTROLLER-SEAL-v7.json')==seal['launch_controller_seal_v7_sha256'],'launch seal');need(sha(ROOT/'launch_controller_v7.py')==seal['launch_controller_v7_sha256'],'controller');need(sha(ROOT/'PERMISSION-v7.json')==seal['launch_permission_v7_sha256'],'permission');need(sha(ROOT/'CONFIG-AUTHORITY-SEAL-v3.json')==seal['config_authority_seal_sha256'],'config seal');need(sha(ROOT/'v6-pre-mutation-clean-block.json')==seal['v6_incident_binding_sha256'],'incident')
 permission=json.loads((ROOT/'PERMISSION-v7.json').read_text());need(permission['status']=='AUTHORIZED_ONE_USE_V7' and permission['v6_permission_reuse_forbidden'] is True,'fresh permission')
 config=PROFILE/'config.yaml';need(sha(config)=='f93106b16643227e2ef9dec67a5bbd497e1d353e779da62287898a087071af87' and stat.S_IMODE(config.stat().st_mode)==0o600 and config.stat().st_uid==1000 and config.stat().st_gid==1000,'config authority')
 proof=json.loads((ROOT/'receipts/actual-profile-preflight-before-permission.json').read_text());need(proof['status']=='PASS_READ_ONLY' and proof['authority_tree_mutations']==0 and proof['credential_output'] is False and proof['credential_resolved'] is True,'actual preflight')
 spec=importlib.util.spec_from_file_location('assembler',ROOT/'assemble_successor.py');assert spec and spec.loader;mod=importlib.util.module_from_spec(spec);spec.loader.exec_module(mod);current=mod.inventory(mod.HERMES,'hermes')+mod.inventory(mod.PROFILE,'profile');need(current==json.loads((ROOT/'product-inventory.json').read_text()),'product inventory')
 text=(ROOT/'launch_controller_v7.py').read_text();need('load_gateway_preflight_inputs' in text and 'load_gateway_'+'config' not in text,'read-only api')
 for lane in ('objective','security','trainer-free','quality','qa','provenance'):need(json.loads((ROOT/f'review-{lane}.json').read_text())['status']=='READY_STRICT_REHEARSAL',lane)
 show=subprocess.run(['/usr/bin/systemctl','--user','show','hermes-gateway-dualcoachtest.service','-p','ActiveState','-p','SubState','-p','MainPID'],text=True,capture_output=True,check=True).stdout;state=dict(x.split('=',1) for x in show.splitlines());need(state=={'MainPID':'0','ActiveState':'inactive','SubState':'dead'},'service clean');need(not (PROFILE/'customers/registry.json').exists() and not (PROFILE/'sessions').exists(),'authority clean')
 print(json.dumps({'status':'READY_STRICT_REHEARSAL','candidate':seal['full_candidate_digest'],'preserved_product_candidate':seal['preserved_product_candidate'],'core':seal['core_candidate_digest'],'package_inventory':seal['package_inventory_sha256'],'readiness_seal_sha256':sha(ROOT/'READINESS-SEAL-v3.json'),'config_authority':'PASS_0600','actual_profile_preflight':'PASS_READ_ONLY_ZERO_MUTATIONS','checks':checks,'clean_state':'PASS'},sort_keys=True));return 0
if __name__=='__main__':
 try:raise SystemExit(main())
 except Exception as exc:print('BLOCKED:',exc,file=sys.stderr);raise SystemExit(2)
