"""Exact-source tool update and isolated field preparation; no service actions."""
import base64
import hashlib
import json
import os
from pathlib import Path
import subprocess
import sys

sys.path.insert(0,'/tmp/codex/ltb1021/2026-09-30_icerti-maintenance-ab_r01')
from remote import root

REPO=Path('/workspace/contextra-analytics-runtime-lifecycle-refactor')
HERE=Path(__file__).resolve().parent
BASE='bc93be6fc42e9c2bb5196b980b015ba2e81a7869'
PREFIX='/usr/local/lib/contextra-maintenance/20260928-r01/'
names=['connection_versions.py','field_diagnostics.py','field_ui.py','network_prepare.py']
sources={PREFIX+n:'tools/icerti_offline/maintenance/'+n for n in names}
sources[PREFIX+'bridge_tools/tools/secure_bridge_enroll.py']='tools/secure_bridge_enroll.py'
rows=[]
for target,source in sources.items():
    data=(REPO/source).read_bytes()
    compile(data,source,'exec')
    old=subprocess.check_output(['git','show',BASE+':'+source],cwd=REPO,timeout=10)
    rows.append({'target':target,'source':source,'before':hashlib.sha256(old).hexdigest(),
                 'after':hashlib.sha256(data).hexdigest(),'payload':base64.b64encode(data).decode()})
ca=Path('/data/codex-artifacts/contextra/field-maintenance/2026/2026-09-30_icerti-ca-backup_r01/manager-ca.crt').read_bytes()
assert hashlib.sha256(ca).hexdigest()=='96a7b202c1e2e8b1964dedfaa1a3a00131345f65efbfad1f5c590f8857eb99b4'
prior=json.loads(Path('/tmp/codex/ltb1021/2026-09-30_icerti-manual-acceptance_r01/password-comparison.json').read_text())
assert prior['icerti_profile_matches_current_candidate'] is True
# The user explicitly approved the same previously verified value for the field account.
# Read the protected value in place; never embed it in code, argv, receipts or tool output.
script=r'''
import base64,fcntl,hashlib,json,os,pwd,subprocess,sys,time,shutil
from pathlib import Path
P=Path;prefix=P('/usr/local/lib/contextra-maintenance/20260928-r01')
sys.path.insert(0,str(prefix));import field_profiles as fp
assert shutil.disk_usage('/').free>15*1024**3
lock=(fp.STATE/'console.lock').open('a');fcntl.flock(lock,fcntl.LOCK_EX|fcntl.LOCK_NB)
assert fp.read_json(fp.STATE/'selected.json')['profile']=='office'
assert not any((fp.STATE/n).exists() for n in ['pending.json','apply-pending.json','network-pending.json'])
runtime=fp.RUNTIME;active=fp.read_json(runtime/'state/active.json',1048576)
assert active['transaction']=='field-20260930T155631-91276'
paths=[runtime/'state'/n for n in ['active.json','site.json','inflight.json']]
paths+=[P('/etc/systemd/system/contextra-runtime.service'),fp.STATE/'selected.json']
paths+=list(P('/etc/netplan').glob('*.yaml'))
paths+=list(fp.PROFILES.glob('*.json'))
paths+=[fp.PROFILES/'office.private/main.credentials.json',fp.PROFILES/'office.private/main.ca.crt']
stage=runtime.parent/'data/site'/active['transaction']
paths+=list(stage.glob('tls/*'))+list(stage.glob('bridge/*'))
paths+=[runtime/'state/transactions'/active['transaction']/'compose.json']
def sha(p):return hashlib.sha256(p.read_bytes()).hexdigest()
protected={str(p):sha(p) for p in paths if p.is_file() and not p.is_symlink()}
def containers():
 names=['contextra-icerti-'+n+'-1' for n in ['analytics','ai-control-sidecar','ai-gateway','redis','postgresql']]
 rows=json.loads(subprocess.check_output(['docker','inspect',*names],timeout=8))
 return [{'name':r['Name'],'id':r['Id'],'image':r['Image'],'running':r['State']['Running']} for r in rows]
before=containers();assert all(c['running'] for c in before)
for row in ROWS:
 p=fp.safe_path(row['target']);assert p.is_file() and sha(p)==row['before'],'Installed drift: '+p.name
 raw=base64.b64decode(row['payload']);assert hashlib.sha256(raw).hexdigest()==row['after'];compile(raw,str(p),'exec')
profile=fp.load('field');credential=fp.secret_path(profile);ca_path=fp.ca_path(profile)
assert not credential.exists() and not ca_path.exists(),'Preserve already prepared field files'
office=fp.secret_path(fp.load('office'));u=pwd.getpwnam('si')
assert office.stat().st_mtime_ns==1790740384695744841,'Reconfirm changed account through hidden input'
value=fp.read_credentials(office);assert value['loginId']=='AI-01'
backup=fp.STATE/('install-preboot-'+time.strftime('%Y%m%dT%H%M%S'))
backup.mkdir(mode=0o700,exist_ok=False)
for row in ROWS:fp.atomic(backup/(Path(row['target']).name+'.before'),P(row['target']).read_bytes())
fp.atomic(backup/'before.json',{'protected':protected,'containers':before,'targets':[{k:v for k,v in r.items() if k!='payload'} for r in ROWS]})
private=credential.parent;fp.safe_path(private);private.mkdir(mode=0o700,exist_ok=True)
os.chown(private,u.pw_uid,u.pw_gid);private.chmod(0o700)
ca_raw=base64.b64decode(CA);assert b'PRIVATE KEY' not in ca_raw
fp.atomic(ca_path,ca_raw,user=True)
sys.path.insert(0,str(prefix/'bridge_tools'));from tools.secure_bridge_tls import public_ca
public_ca(ca_path)
subprocess.run(['openssl','verify','-CAfile',str(ca_path),str(ca_path)],check=True,capture_output=True,timeout=5)
fp.atomic(credential,{'loginId':'AI-01','password':value['password']},user=True)
assert fp.read_credentials(credential)==value
for row in ROWS:fp.atomic(row['target'],base64.b64decode(row['payload']),mode=0o644)
assert all(sha(P(p))==v for p,v in protected.items()),'Protected Runtime drift'
assert before==containers(),'Container state changed'
result={'status':'TOOLS_AND_FIELD_READY_NOT_ACTIVATED','backup':str(backup),
 'installed':{r['target']:sha(P(r['target'])) for r in ROWS},'protected_equal':True,
 'containers_preserved':True,'active_transaction':active['transaction'],'selected':'office',
 'field_ca_sha256':sha(ca_path),'field_credentials_ready':True,'field_login_id':'AI-01',
 'credential_source':'user-approved value from previously verified unchanged protected record; independent field file',
 'field_private_owner':private.stat().st_uid,'field_private_mode':oct(private.stat().st_mode&0o777),
 'field_credentials_mode':oct(credential.stat().st_mode&0o777),'field_network_activated':False,
 'login_requests':0,'services_restarted':0,'reboot_executed':False}
fp.atomic(backup/'receipt.json',result);print(json.dumps(result))
'''
result=json.loads(root('ROWS='+repr(rows)+'\nCA='+repr(base64.b64encode(ca).decode())+'\n'+script,timeout=45))
os.umask(0o077)
(HERE/'installation.json').write_text(json.dumps(result,ensure_ascii=False,indent=2)+'\n')
print(json.dumps(result,ensure_ascii=False))
