"""Gate-bound read-only Windows fixture lint. Prepared; parent supplies closed pins.""" from pathlib import Path from datetime import datetime, timezone import argparse, hashlib, json, os, re, shutil, subprocess, sys, zipfile BASE = Path(__file__).resolve().parent DLL_SHA = 'f45604a12e8bcd839fd86f667c1be1cc7c4f9da2b3c69ff381ac708f0e1ae7d4' def now(): return datetime.now(timezone.utc).isoformat() def ident(p): raw = p.read_bytes() return {'bytes': len(raw), 'sha256': hashlib.sha256(raw).hexdigest()} def read(p): return json.loads(p.read_text(encoding='utf-8')) def require(ok, message): if not ok: raise ValueError(message) def pin(p, sha): require(p.is_absolute() and re.fullmatch('[0-9a-f]{64}', sha), 'absolute path and SHA256 required') require(ident(p)['sha256'] == sha, f'pin mismatch: {p}') def tree(p): return {f.relative_to(p).as_posix(): ident(f) for f in sorted(p.rglob('*')) if f.is_file()} def gate(path, sha): pin(path, sha); r = read(path); d = path.parent require(r['exitCode'] == 0 and r['inputsUnchanged'] is True and r['finish'], 'completed successful unchanged-source gate required') for name, key in [('inputs.json','inputs'), ('inputs.zip','archive'), ('stdout.log','stdout'), ('stderr.log','stderr')]: require(ident(d/name) == r[key], f'gate record mismatch: {name}') rows = read(d/'inputs.json') require(len(rows) == r['inputCount'], 'source count mismatch') with zipfile.ZipFile(d/'inputs.zip') as z: require(len(z.namelist()) == len(rows) and set(z.namelist()) == set(rows), 'exact input membership required') for name, expected in rows.items(): raw = z.read(name) require({'bytes':len(raw),'sha256':hashlib.sha256(raw).hexdigest()} == expected, 'input ZIP byte/CRC binding failed') return r, rows def main(): ap=argparse.ArgumentParser() for name in ['cli','build-result','build-sha','source-result','source-sha','label']: ap.add_argument('--'+name, required=True) a=ap.parse_args(); require(os.name == 'nt', 'Windows-only evaluator') require(re.fullmatch('current-oracle-[a-z0-9-]+', a.label), 'fresh bounded output label required') binary=Path(a.cli); require(binary.is_absolute() and binary.suffix.lower()=='.exe', 'preserved Windows CLI path required') build, rows=gate(Path(a.build_result), a.build_sha) source, source_rows=gate(Path(a.source_result), a.source_sha) require(rows == source_rows, 'CLI build and completed source acceptance inputs differ') require('build' in build['command'] and build['environment']['RUSTUP_TOOLCHAIN']=='stable-x86_64-pc-windows-gnullvm', 'actual Windows build receipt required, not a test binary') matches=[v for v in build['artifacts'] if v['cargo']['target']['name']=='arcadia' and v['cargo']['target']['kind']==['bin'] and v['cargo']['profile']['test'] is False and v['cargo']['executable']] require(len(matches)==1, 'exactly one non-test arcadia Cargo artifact required') artifact=matches[0]; before=ident(binary); require(before==artifact['readback'], 'preserved CLI differs from Cargo artifact readback') require(Path(artifact['cargo']['manifest_path']).resolve()==(Path(build['cwd'])/'crates/oa-cli/Cargo.toml').resolve() and 'crates/oa-cli/Cargo.toml' in rows, 'artifact must belong to captured oa-cli crate') if '--target' in build['command']: require(build['command'][build['command'].index('--target')+1]=='x86_64-pc-windows-gnullvm', 'non-Windows target rejected') raw_artifacts=[] for line in (Path(a.build_result).parent/'stdout.log').read_text(encoding='utf-8').splitlines(): try: value=json.loads(line) except json.JSONDecodeError: continue if isinstance(value,dict) and value.get('reason')=='compiler-artifact': raw_artifacts.append(value) require(artifact['cargo'] in raw_artifacts, 'artifact is not present in bound raw Cargo output') evidence_before={str(p):ident(p) for result in [Path(a.build_result),Path(a.source_result)] for p in [result,*[result.parent/n for n in ['inputs.json','inputs.zip','stdout.log','stderr.log']]]} dll=BASE/'runtime/libunwind.dll'; require(ident(dll)['sha256']==DLL_SHA,'runtime DLL mismatch') fixture_before=tree(BASE/'fixtures') require(set(fixture_before)=={'missing-include/project.arcadia','functions-to-discover.arcadia'}, 'unexpected fixture membership') out=BASE/a.label; out.mkdir() record={'started':now(),'scope':'Current source-bound Windows CLI lint of saved fixture bytes only; no GUI, unsaved model, Linux or release acceptance.', 'helper':ident(Path(__file__)), 'binaryPath':str(binary),'binary':before,'artifact':artifact,'buildResult':{'path':a.build_result,'sha256':a.build_sha},'sourceResult':{'path':a.source_result,'sha256':a.source_sha},'sourceFiles':len(rows),'sourceInputs':build['inputs'],'fixtures':fixture_before,'runs':[],'passed':False} try: for name in ['missing','complete','cwd','profile','tmp']: (out/name).mkdir() for name in ['missing','complete']: shutil.copyfile(BASE/'fixtures/missing-include/project.arcadia',out/name/'project.arcadia') shutil.copyfile(BASE/'fixtures/functions-to-discover.arcadia',out/'complete/functions.arcadia') prepared={name:tree(out/name) for name in ['missing','complete']} inherited={k.upper():v for k,v in os.environ.items()}; system=inherited['SYSTEMROOT'] env={'SystemRoot':system,'WINDIR':system,'SystemDrive':inherited['SYSTEMDRIVE'],'PATH':str(binary.parent)+';'+str(dll.parent)+';'+system+'\\System32;'+system,'USERPROFILE':str(out/'profile'),'TEMP':str(out/'tmp'),'TMP':str(out/'tmp')} record['environment']=env; record['preparedFixtures']=prepared for label, expected in [('missing',3),('complete',0)]: argv=[str(binary),'lint',str(out/label/'project.arcadia'),'--json']; run={'label':label,'started':now(),'command':argv,'expectedExitCode':expected}; record['runs'].append(run) with (out/(label+'.stdout.json')).open('xb') as stdout, (out/(label+'.stderr.log')).open('xb') as stderr: try: result=subprocess.run(argv,cwd=out/'cwd',env=env,stdout=stdout,stderr=stderr,timeout=55,creationflags=subprocess.CREATE_NO_WINDOW) run['exitCode']=result.returncode except (OSError,subprocess.TimeoutExpired) as error: run['failure']=repr(error); raise finally: run['finished']=now() run['stdout']=ident(out/(label+'.stdout.json'));run['stderr']=ident(out/(label+'.stderr.log')) report=read(out/(label+'.stdout.json'));run['report']=report require(result.returncode==expected and report['exit_code']==expected, 'unexpected CLI/report exit') require(report['written'] is False and report['operation']=='check' and report['changes']==[], 'lint must not write or propose rewrites') require(report['status']==('invalid' if label=='missing' else 'checked'), 'unexpected lint status') require(isinstance(report['diagnostics'],list), 'missing exact diagnostic list') if label=='missing': require(any(d['code']=='missing_include' and d['severity']=='error' for d in report['diagnostics']), 'missing include fixture did not produce expected error') else: require(report['diagnostics'] and all(d['severity']=='warning' for d in report['diagnostics']), 'complete raw fixture must retain warnings without errors') require(tree(out/label)==prepared[label], 'CLI mutated physical fixture bytes') record['passed']=True except Exception as error: record['failure']=repr(error) finally: record['finished']=now();record['binaryUnchanged']=ident(binary)==before;record['originalFixturesUnchanged']=tree(BASE/'fixtures')==fixture_before;record['dllUnchanged']=ident(dll)['sha256']==DLL_SHA record['evidenceUnchanged']=all(Path(p).is_file() and ident(Path(p))==v for p,v in evidence_before.items()) record['passed']=record['passed'] and record['binaryUnchanged'] and record['originalFixturesUnchanged'] and record['dllUnchanged'] and record['evidenceUnchanged'] for run in record['runs']: for suffix,key in [('.stdout.json','stdout'),('.stderr.log','stderr')]: p=out/(run['label']+suffix) if p.exists(): run[key]=ident(p) with (out/'result.json').open('x',encoding='utf-8',newline='\n') as f: json.dump(record,f,indent=2);f.write('\n') print(json.dumps({'output':str(out),'passed':record['passed'],'receipt':ident(out/'result.json')}),flush=True) return 0 if record['passed'] else 1 if __name__=='__main__': sys.exit(main())