"""Producer non-execution readback; independent review remains separate.""" import hashlib import json from pathlib import Path import subprocess import zipfile from datetime import datetime, timezone BASE = Path(__file__).resolve().parent NAME = 'ArcadiaStudio-0.2.0-preview.contextual.20260911-x86_64-pc-windows-gnullvm' ZIP = BASE / 'packages' / (NAME + '.zip') STAGE = BASE / 'packages' / NAME EXPECTED = '9186d4fc9a7b52fb195c183c4847c8e3419ea6da8b3f907e0c06f9ceec58dee0' def sha(path): with path.open('rb') as stream: return hashlib.file_digest(stream, 'sha256').hexdigest() assert sha(ZIP) == EXPECTED result = {'read_at': datetime.now(timezone.utc).isoformat(), 'archive': str(ZIP), 'archive_sha256': EXPECTED, 'archive_bytes': ZIP.stat().st_size} actual = {} with zipfile.ZipFile(ZIP) as archive: names = archive.namelist() assert len(names) == len(set(names)) == len({n.casefold() for n in names}) == 559 for entry in archive.infolist(): assert entry.filename.startswith(NAME + '/') and not entry.is_dir() relative = entry.filename[len(NAME) + 1:] assert '..' not in Path(relative).parts and not Path(relative).is_absolute() assert entry.date_time == (2000, 1, 1, 0, 0, 0) with archive.open(entry) as stream: checksum = hashlib.file_digest(stream, 'sha256').hexdigest() assert checksum == sha(STAGE / relative), relative actual[relative] = {'bytes': entry.file_size, 'sha256': checksum} assert set(actual) == {p.relative_to(STAGE).as_posix() for p in STAGE.rglob('*') if p.is_file()} expected_manifest = {} for line in (STAGE / 'SHA256SUMS.txt').read_text(encoding='utf-8').splitlines(): checksum, path = line.split(' ', 1) assert path not in expected_manifest expected_manifest[path] = checksum assert set(expected_manifest) == set(actual) - {'SHA256SUMS.txt'} for path, checksum in expected_manifest.items(): assert actual[path]['sha256'] == checksum package = json.loads((STAGE / 'package.json').read_text(encoding='utf-8-sig')) notices = json.loads((STAGE / 'dependency-notices.json').read_text(encoding='utf-8-sig')) docs = json.loads((STAGE / 'documentation-check.json').read_text(encoding='utf-8-sig')) prepared = json.loads((BASE / 'preparation.json').read_text(encoding='utf-8')) for path, checksum in prepared['gui_inputs'].items(): assert sha(BASE / 'source' / path) == checksum for path, checksum in prepared['server_inputs'].items(): assert sha(BASE / 'source' / path) == checksum for path, checksum in prepared['shared_non_cargo_inputs'].items(): assert sha(BASE / 'source' / path) == checksum assert not subprocess.check_output(['git', 'status', '--porcelain'], cwd=BASE / 'source') result.update({'files': actual, 'file_count': len(actual), 'manifest_entries': len(expected_manifest), 'dependency_packages': len(notices['packages']), 'notice_roots': notices['root_packages'], 'documentation_check': docs, 'binary_imports': package['imports'], 'source_commit': prepared['reconstruction_commit'], 'gui_inputs_unchanged': 238, 'server_inputs_unchanged': 120, 'shared_inputs_unchanged': 5, 'source_worktree_clean': True, 'scope': 'Producer readback only; no extraction or executable/runtime launch.'}) with (BASE / 'package-readback.json').open('x', encoding='utf-8', newline='\n') as output: json.dump(result, output, indent=2) output.write('\n') print(json.dumps({k: v for k, v in result.items() if k != 'files'}, indent=2))