Files
ARCADIA-Studio/harness/experiments/resize-port-policy-20260912/run-policy-gates.py
T

98 lines
5.1 KiB
Python

"""Serialized, stamped core-only experiment gates; never uses root target artifacts."""
from pathlib import Path
from datetime import datetime, timezone
import hashlib
import json
import os
import shutil
import subprocess
import time
worktree = Path(__file__).resolve().parent.parent
root = worktree.parent.parent
source = '7e25b3d3907693cbbf03bb51b5e08b01d743a934'
out = worktree / '.local' / 'gate-7e25b3d-20260912-01'
target = worktree / '.local' / 'target-7e25b3d-01'
assert not out.exists() and not target.exists(), 'Never overwrite identified gate outputs'
assert target.resolve().is_relative_to(worktree / '.local')
assert target.resolve() != (root / 'target').resolve()
out.mkdir()
def utc():
return datetime.now(timezone.utc).isoformat()
def sha(path):
return hashlib.sha256(path.read_bytes()).hexdigest()
def checked(args):
return subprocess.check_output(args, cwd=worktree, stderr=subprocess.STDOUT).decode().strip()
def write(name, record):
(out / name).write_text(json.dumps(record, indent=2) + '\n', encoding='utf-8', newline='\n')
assert checked(['git', 'rev-parse', 'HEAD']) == source
assert not checked(['git', 'status', '--porcelain', '--untracked-files=no'])
tracked = subprocess.check_output(['git', 'ls-files', '-z'], cwd=worktree).decode().split('\0')
inputs = [name for name in tracked if name and (
name.startswith(('crates/oa-core/', '.cargo/'))
or name in ['Cargo.toml', 'Cargo.lock', 'rust-toolchain.toml']
or name.endswith('/Cargo.toml'))]
before = {name: sha(worktree / name) for name in inputs}
protected_paths = [root / 'target/debug/deps/liboa_core-145180297aa692e4.rlib', root / '.local/toolchain/env.ps1']
protected = {str(path): sha(path) for path in protected_paths}
env = os.environ.copy()
env['CARGO_TARGET_DIR'] = str(target)
env['CARGO_BUILD_JOBS'] = '1'
tools = {
'cargo': checked(['cargo', '-V']),
'rustc': checked(['rustc', '-Vv']),
'active_toolchain': checked(['rustup', 'show', 'active-toolchain']),
'paths': {},
}
for tool in ['cargo', 'rustc']:
path = Path(checked(['rustup', 'which', tool]))
tools['paths'][tool] = {'path': str(path), 'sha256': sha(path)}
linker = Path(shutil.which('clang.exe'))
tools['paths']['linker'] = {'path': str(linker), 'sha256': sha(linker)}
write('inputs.json', {'source': source, 'start': utc(), 'worktree': str(worktree),
'target': str(target), 'inputs': before, 'protected': protected, 'toolchain': tools,
'environment': {key: env.get(key) for key in [
'CARGO_HOME', 'RUSTUP_HOME', 'CARGO_TARGET_DIR', 'CARGO_BUILD_JOBS',
'CARGO_TARGET_X86_64_PC_WINDOWS_GNULLVM_LINKER']}})
gates = [
('comparison', ['cargo', 'test', '--locked', '--jobs', '1', '-p', 'oa-core', '--test', 'experimental_port_policy', '--', '--nocapture', '--test-threads=1']),
('allocator', ['cargo', 'test', '--locked', '--jobs', '1', '-p', 'oa-core', '--lib', 'port_capacity_experiment', '--', '--nocapture', '--test-threads=1']),
('port-anchors', ['cargo', 'test', '--locked', '--jobs', '1', '-p', 'oa-core', '--test', 'port_anchors', '--', '--nocapture', '--test-threads=1']),
]
results = []
for name, command in gates:
started = utc()
clock = time.monotonic()
print(f'START {name}: {command}', flush=True)
with (out / (name + '.log')).open('wb') as log:
result = subprocess.run(command, cwd=worktree, env=env, stdout=log, stderr=subprocess.STDOUT)
changed = [name for name, digest in before.items() if sha(worktree / name) != digest]
protected_changed = [name for name, digest in protected.items() if sha(Path(name)) != digest]
artifacts = []
for folder in [target / 'debug/deps', target / 'x86_64-pc-windows-gnullvm/debug/deps']:
if folder.is_dir():
for pattern in ['liboa_core-*.rlib', 'experimental_port_policy-*.exe', 'oa_core-*.exe', 'port_anchors-*.exe']:
for path in folder.glob(pattern):
artifacts.append({'path': str(path.relative_to(worktree)), 'bytes': path.stat().st_size, 'sha256': sha(path)})
record = {'source': source, 'name': name, 'command': command, 'start': started, 'end': utc(),
'elapsed_seconds': round(time.monotonic() - clock, 3), 'exit': result.returncode,
'changed_inputs': changed, 'changed_protected': protected_changed,
'head_after': checked(['git', 'rev-parse', 'HEAD']), 'log_sha256': sha(out / (name + '.log')),
'artifacts': artifacts}
write(name + '.json', record)
results.append(record)
print(f'END {name}: exit={result.returncode} seconds={record["elapsed_seconds"]} changed={changed} protected_changed={protected_changed}', flush=True)
if result.returncode or changed or protected_changed or record['head_after'] != source:
break
write('summary.json', {'source': source, 'end': utc(), 'results': results,
'all_passed': len(results) == len(gates) and all(r['exit'] == 0 and not r['changed_inputs'] and not r['changed_protected'] for r in results)})
print(f'RECEIPTS {out}', flush=True)
raise SystemExit(0 if len(results) == len(gates) and all(r['exit'] == 0 and not r['changed_inputs'] and not r['changed_protected'] for r in results) else 1)