"""Bounded final fingerprints, local link/syntax validation and trial inventory."""
import ast,hashlib,json,re,subprocess,sys
from pathlib import Path
import deploy
repo=deploy.REPO;root=deploy.ROOT
paths=subprocess.check_output(['git','diff','--name-only'],cwd=repo).decode().splitlines()
paths+=subprocess.check_output(['git','ls-files','--others','--exclude-standard'],cwd=repo).decode().splitlines()
paths=sorted(set(paths));links=[]
for name in paths:
 p=repo/name
 if p.suffix=='.py':ast.parse(p.read_text())
 if p.suffix=='.json':json.loads(p.read_text())
 if p.suffix!='.md':continue
 for target in re.findall(r'\]\(([^)]+)\)',p.read_text()):
  if target.startswith(('http:','https:','#','mailto:')):continue
  target=target.split('#',1)[0]
  resolved=Path(target) if target.startswith('/') else (p.parent/target).resolve()
  if not resolved.exists():links.append(dict(file=name,target=target))
assert not links,links
subprocess.run(['git','diff','--check'],cwd=repo,check=True)
sys.path.insert(0,'/data/codex-artifacts/contextra/action-model-eval/2026/2026-11-01_contextra-fall-r2-runtime_r01/helpers')
import control_runtime as c
code='import json,hashlib;from pathlib import Path;r=Path('+repr(c.c.REMOTE+'/download')+');print(json.dumps({str(p.relative_to(r)):hashlib.sha256(p.read_bytes()).hexdigest() for p in r.rglob("*") if p.is_file()}))'
remote=json.loads(c.c.old.checked(['python3','-c',code]))
assert remote and all(hashlib.sha256((c.ROOT/'results'/n).read_bytes()).hexdigest()==h for n,h in remote.items())
(c.ROOT/'reports/transfer_sha256.json').write_text(json.dumps(dict(status='PASS',files=remote),indent=2))
code="""import json,subprocess
rows=subprocess.run(['docker','ps','-a','--format','{{.Names}}'],capture_output=True,check=True).stdout.decode().splitlines()
prefixes=('contextra-fallruntime-1101-r01-','ct-fall-r2-','ct-artifact-import-icerti-ai2')
own=[n for n in rows if n.startswith(prefixes)]
print(json.dumps(dict(trial_containers_remaining=own)))
assert not own
"""
trials=json.loads(deploy.r.python(code,sudo=True))
manifest={n:hashlib.sha256((repo/n).read_bytes()).hexdigest() for n in paths}
result=dict(status='PASS',repo_head=subprocess.check_output(['git','rev-parse','HEAD'],cwd=repo).decode().strip(),
 changed_paths=manifest,links_missing=links,syntax=True,diff_check=True,replay_transferred_files=len(remote),**trials)
(root/'final-validation.json').write_text(json.dumps(result,ensure_ascii=False,indent=2))
print(json.dumps({k:v for k,v in result.items() if k!='changed_paths'},ensure_ascii=False))
