import base64,hashlib,importlib.util,json,subprocess,sys
from pathlib import Path
spec=importlib.util.spec_from_file_location('transport','/tmp/codex/ltb1021/2026-10-06_icerti-ai2-deploy_r01/remote.py')
remote=importlib.util.module_from_spec(spec);spec.loader.exec_module(remote)
repo=Path('/workspace/contextra-analytics-runtime-lifecycle-refactor')
run=Path(__file__).parent
files=['data_worker.py','data_host.py']
receipt=run/'installed-hashes.json'
old=json.loads(receipt.read_text()) if receipt.exists() else {n:hashlib.sha256(subprocess.check_output(['git','-C',str(repo),'show','HEAD:tools/icerti_offline/maintenance/'+n],timeout=10)).hexdigest() for n in files}
payload={n:base64.b64encode((repo/'tools/icerti_offline/maintenance'/n).read_bytes()).decode() for n in files}
code='OLD='+repr(old)+'\nPAYLOAD='+repr(payload)+'\n'+r'''
import base64,hashlib,json,signal,sys,time,shutil
from pathlib import Path
signal.alarm(30)
prefix=Path('/usr/local/lib/contextra-maintenance/portable-20261006T192646');sys.path.insert(0,str(prefix))
import field_profiles as fp,server_context as server
server.verify_tools();assert shutil.disk_usage('/').free>=15*1024**3
inventory_path=prefix/'installed-files.json';inventory=json.loads(inventory_path.read_text())
changed=[n for n in OLD if hashlib.sha256(base64.b64decode(PAYLOAD[n])).hexdigest()!=OLD[n]]
assert changed,'NO_CHANGE'
for n in OLD:assert hashlib.sha256((prefix/n).read_bytes()).hexdigest()==OLD[n] and inventory[n]==OLD[n],'SOURCE_CONFLICT'
backup=fp.STATE/'data-tool-updates'/str(time.time_ns());backup.mkdir(parents=True,mode=0o700)
fp.atomic(backup/'installed-files.json',inventory_path.read_bytes())
for n in changed:
    fp.atomic(backup/n,(prefix/n).read_bytes());raw=base64.b64decode(PAYLOAD[n]);fp.atomic(prefix/n,raw,mode=0o644);inventory[n]=hashlib.sha256(raw).hexdigest()
fp.atomic(inventory_path,inventory,mode=0o644);server.verify_tools()
fp.atomic(backup/'receipt.json',dict(changed=changed,before=OLD,after={n:inventory[n] for n in OLD}))
print(json.dumps(dict(backup=str(backup),hashes={n:inventory[n] for n in OLD})))
'''
data=json.loads(remote.run(code,root=True,timeout=40));receipt.write_text(json.dumps(data['hashes']));receipt.chmod(0o600)
(run/('patch-'+sys.argv[1]+'.json')).write_text(json.dumps(data,indent=2)+'\n')
print(json.dumps(data))
