"""Read-only primary provenance capture. Never invokes a compiler or application.""" from pathlib import Path import hashlib, json, urllib.request, zipfile, re ROOT = Path(__file__).resolve().parents[2] OUT = Path(__file__).resolve().parent def sha(b): return hashlib.sha256(b).hexdigest() def new(name, b): with (OUT / name).open('xb') as f: f.write(b) def fetch(url, name): req = urllib.request.Request(url, headers={'User-Agent':'Arcadia-runtime-provenance/1'}) with urllib.request.urlopen(req, timeout=45) as r: b = r.read() info = {'url':url, 'final_url':r.url, 'status':r.status, 'bytes':len(b), 'sha256':sha(b)} new(name,b) return b, info release_b, release_info = fetch('https://api.github.com/repos/mstorsjo/llvm-mingw/releases/tags/20260908', 'official-release.json') release = json.loads(release_b) asset = next(a for a in release['assets'] if a['name']=='llvm-mingw-20260908-ucrt-x86_64.zip') archive = ROOT / '.local/toolchain/llvm-mingw.zip' archive_hash = sha(archive.read_bytes()) assert archive.stat().st_size == asset['size'] assert asset['digest'] == 'sha256:' + archive_hash rows=[] with zipfile.ZipFile(archive) as z: for suffix in ['x86_64-w64-mingw32/bin/libunwind.dll','bin/libunwind.dll','LICENSE.TXT']: name='llvm-mingw-20260908-ucrt-x86_64/'+suffix b=z.read(name) local=ROOT/'.local/toolchain'/name assert b==local.read_bytes() rows.append({'member':name,'bytes':len(b),'sha256':sha(b),'crc':z.getinfo(name).CRC,'local_path':str(local)}) if suffix=='LICENSE.TXT':new('distribution-LICENSE.TXT',b) # Compiler binary strings are corroborative metadata only; do not execute it. b=z.read('llvm-mingw-20260908-ucrt-x86_64/bin/clang.exe') strings=[x.decode('ascii') for x in re.findall(rb'[ -~]{16,}',b) if b'github.com/llvm/llvm-project' in x or b'clang version 23' in x] new('compiler-embedded-version-strings.json',json.dumps(strings,indent=2).encode()) tag_b, tag_info=fetch('https://api.github.com/repos/mstorsjo/llvm-mingw/git/ref/tags/20260908','official-tag.json') tag=json.loads(tag_b) new('initial-evidence.json',json.dumps({'release':release_info,'asset':asset,'archive':{'path':str(archive),'bytes':archive.stat().st_size,'sha256':archive_hash},'archive_members':rows,'tag':tag_info,'tag_object':tag['object']},indent=2).encode()) print(json.dumps({'asset':asset,'archive_sha256':archive_hash,'members':rows,'tag':tag['object'],'compiler_strings':strings},indent=2))