Files
ARCADIA-Studio/harness/experiments/default-policy-20260913/gate-policy.py
T

45 lines
3.0 KiB
Python

from pathlib import Path
import datetime, hashlib, json, os, subprocess, sys, time, zipfile
# Process-local disk recovery: do not write another Rust incremental cache.
os.environ['CARGO_INCREMENTAL'] = '0'
root = Path('C:/ar-default-9e8r6t')
out = Path(__file__).resolve().parent / sys.argv[1]
out.mkdir(parents=True, exist_ok=False)
def now(): return datetime.datetime.now(datetime.timezone.utc).isoformat()
def digest(path):
data = path.read_bytes()
return {'bytes': len(data), 'sha256': hashlib.sha256(data).hexdigest()}
def inputs():
paths = subprocess.check_output(['git','ls-files','--cached','--others','--exclude-standard','-z'],cwd=root).decode().split('\0')
return {p:digest(root/p) for p in sorted(set(paths)) if p and (p in ('Cargo.toml','Cargo.lock') or p.startswith(('crates/','build/','.cargo/','docs/','examples/','harness/fixtures/','harness/prototypes/')))}
before=inputs()
(out/'inputs.json').write_text(json.dumps(before,indent=2),encoding='utf-8')
with zipfile.ZipFile(out/'inputs.zip','x',compression=zipfile.ZIP_DEFLATED) as z:
for p in before: z.write(root/p,p)
command=['cargo',*sys.argv[2:]]
start={'start':now(),'command':command,'cwd':str(root),'head':subprocess.check_output(['git','rev-parse','HEAD'],cwd=root,text=True).strip(),
'scope':'All Git-visible Cargo manifests/lock, crates (including patched dependency), build, .cargo, docs, examples, harness fixtures and compiled prototypes; packaging scripts have separate verification',
'inputs':digest(out/'inputs.json'),'archive':digest(out/'inputs.zip'),'inputCount':len(before),
'environment':{k:os.environ.get(k) for k in ('RUSTUP_TOOLCHAIN','CARGO_HOME','CARGO_TARGET_DIR','CARGO_BUILD_JOBS','CARGO_INCREMENTAL')},
'helper':digest(Path(__file__).resolve()),
'cargo':subprocess.check_output(['cargo','--version'],text=True).strip(),'rustc':subprocess.check_output(['rustc','--version'],text=True).strip()}
(out/'started.json').write_text(json.dumps(start,indent=2),encoding='utf-8')
t=time.perf_counter()
with (out/'stdout.log').open('xb') as stdout,(out/'stderr.log').open('xb') as stderr:
r=subprocess.run(command,cwd=root,stdout=stdout,stderr=stderr)
artifacts=[]
for line in (out/'stdout.log').read_text(encoding='utf-8',errors='replace').splitlines():
try: item=json.loads(line)
except json.JSONDecodeError: continue
if isinstance(item,dict) and item.get('reason')=='compiler-artifact' and item.get('executable'):
path=Path(item['executable'])
artifacts.append({'cargo':item,'readback':digest(path) if path.exists() else None})
result={**start,'finish':now(),'seconds':time.perf_counter()-t,'exitCode':r.returncode,'inputsUnchanged':before==inputs(),
'stdout':digest(out/'stdout.log'),'stderr':digest(out/'stderr.log'),'artifacts':artifacts}
(out/'result.json').write_text(json.dumps(result,indent=2),encoding='utf-8')
print(json.dumps({k:v for k,v in result.items() if k!='artifacts'},indent=2))
print('Executable artifacts:',len(artifacts))
sys.exit(0 if r.returncode==0 and result['inputsUnchanged'] else 1)