Files
ARCADIA-Studio/harness/experiments/default-production-20260913/verify.py
T

58 lines
4.2 KiB
Python

from pathlib import Path
import hashlib
import io
import json
import re
import zipfile
root = Path(__file__).resolve().parent
def digest(data): return {'bytes':len(data), 'sha256':hashlib.sha256(data).hexdigest()}
def require(ok, message):
if not ok: raise SystemExit(message)
manifest = json.loads((root / 'files.json').read_text())
actual = {p.relative_to(root).as_posix() for p in root.rglob('*') if p.is_file() and p.name != 'files.json' and '__pycache__' not in p.parts}
require(actual == set(manifest), 'Outer membership mismatch')
for name, expected in manifest.items(): require(digest((root/name).read_bytes()) == expected, f'Outer hash: {name}')
with zipfile.ZipFile(root / 'evidence.zip') as evidence:
def read(name): return json.loads(evidence.read(name))
payloads = read('capture-files.json')
require(set(evidence.namelist()) == set(payloads) | {'capture-files.json'}, 'Capture membership mismatch')
for name, expected in payloads.items(): require(digest(evidence.read(name)) == expected, f'Capture hash: {name}')
for gate, status in [('production-focused-1',0),('production-core-1',101)]:
result = read(gate+'/result.json')
require(result['exitCode'] == status and result['inputsUnchanged'], f'{gate}: outcome')
require(all(result[k] == v for k,v in read(gate+'/started.json').items()), f'{gate}: start')
for key, file in [('inputs','inputs.json'),('archive','inputs.zip'),('stdout','stdout.log'),('stderr','stderr.log')]:
require(digest(evidence.read(gate+'/'+file)) == result[key], f'{gate}: {key}')
require(digest(evidence.read('gate-policy.py')) == result['helper'], f'{gate}: runner')
inputs = read(gate+'/inputs.json')
require(len(inputs) == result['inputCount'], f'{gate}: input count')
with zipfile.ZipFile(io.BytesIO(evidence.read(gate+'/inputs.zip'))) as sources:
require(set(sources.namelist()) == set(inputs), f'{gate}: source membership')
for path, expected in inputs.items(): require(digest(sources.read(path)) == expected, f'{gate}: source {path}')
def totals(prefix, filenames):
rows = [tuple(map(int,m)) for f in filenames for m in re.findall(r'test result: (?:ok|FAILED)\. (\d+) passed; (\d+) failed; (\d+) ignored;', evidence.read(prefix+f).decode())]
return tuple(sum(row[i] for row in rows) for i in range(3))
require(totals('production-focused-1/', ['stdout.log']) == (75,0,0), 'Focused totals')
require(b'No space left on device' in evidence.read('production-core-1/stdout.log'), 'Missing disk failure evidence')
built = read('production-built-tests-1/results.json')
compiler = {r['cargo']['target']['name']:r for r in read('production-core-1/result.json')['artifacts']}
require(len(built) == 36, 'Built test inventory')
for run in built:
name = run['name']
require(run['binary'] == compiler[name]['readback'], f'{name}: binary receipt')
for stream in ['stdout','stderr']:
require(digest(evidence.read(f'production-built-tests-1/{name}.{stream}.log')) == run[stream], f'{name}: stream')
require(totals('production-built-tests-1/', [r['name']+'.stdout.log' for r in built]) == (354,2,1), 'Built test totals')
receipt = read('production-built-tests-1/receipt.json')
require(receipt['inputsUnchanged'] and receipt['testsRun'] == 36, 'Execution receipt')
teaching = read('production-teaching-1/result.json')
require(teaching['nonSourceFilesUnchanged'] and len(teaching['changed']) == 29, 'Teaching delta')
require(all(p.endswith('.arcadia') for p in teaching['changed']), 'Non-source teaching change')
for run in teaching['runs']:
require(run['exitCode'] == 0 and run['binary'] == compiler[run['name']]['readback'], 'Teaching runner receipt')
require(totals('production-teaching-1/', ['release1_teaching.stdout.log']) == (4,0,0), 'Teaching rerun')
require(read('language-doc-3/result.json')['warnings']['bytes'] == 0, 'Documentation warnings')
print('Verified captures: focused 75 pass; disk-limited build; separately executed 354 pass/2 fail/1 ignored; teaching rerun 4 pass.')
print('Final candidate still needs corrected anchor test, full core, strict Clippy, native/public-consumer and release verification.')