208 lines
14 KiB
Python
208 lines
14 KiB
Python
"""Verify saved bytes, receipts and Git identities. Never launch application/oracle code."""
|
|
from pathlib import Path
|
|
import argparse
|
|
import hashlib
|
|
import io
|
|
import json
|
|
import subprocess
|
|
import sys
|
|
|
|
if sys.flags.optimize:
|
|
raise SystemExit('Optimized Python is forbidden; no checks may be disabled')
|
|
|
|
SOURCE = '44095f78c28b79d6d085863dc928adba8e24d955'
|
|
ORACLE = 'e1240295bd114d23d3f67a69e6b38bdb2e25bb0d'
|
|
BASE = 'cccd66c5d522497dbecb28ce722644848943d009'
|
|
ORIGINAL_ROOT = 'C:/Users/User/Documents/Git/ARCADIA-Studio/'
|
|
ARCHIVE = Path(__file__).resolve().parent
|
|
ROOT = ARCHIVE.parents[2]
|
|
|
|
def require(value, message):
|
|
if not value:
|
|
raise ValueError(message)
|
|
|
|
def identity(data):
|
|
return {'bytes': len(data), 'sha256': hashlib.sha256(data).hexdigest()}
|
|
|
|
def binding(row):
|
|
return {key: row[key] for key in ('bytes', 'sha256')}
|
|
|
|
def read(path):
|
|
return json.loads(path.read_bytes())
|
|
|
|
def canonical(value):
|
|
return hashlib.sha256(json.dumps(value, sort_keys=True, separators=(',', ':')).encode()).hexdigest()
|
|
|
|
def inventory(folder):
|
|
items = list(folder.rglob('*'))
|
|
require(all(not p.is_symlink() for p in items), 'Symlink in fixture')
|
|
return {'directories': sorted(p.relative_to(folder).as_posix() for p in items if p.is_dir()),
|
|
'files': {p.relative_to(folder).as_posix(): identity(p.read_bytes()) for p in sorted(items) if p.is_file()}}
|
|
|
|
def blobs(specs):
|
|
output = subprocess.check_output(['git', '-c', 'core.longpaths=true', 'cat-file', '--batch'],
|
|
cwd=ROOT, input=('\n'.join(specs) + '\n').encode())
|
|
stream = io.BytesIO(output)
|
|
result = []
|
|
for spec in specs:
|
|
parts = stream.readline().split()
|
|
require(len(parts) == 3 and parts[1] == b'blob', 'Missing Git blob: ' + spec)
|
|
data = stream.read(int(parts[2]))
|
|
require(len(data) == int(parts[2]) and stream.read(1) == b'\n', 'Malformed Git batch')
|
|
result.append(data)
|
|
require(not stream.read(), 'Trailing Git batch bytes')
|
|
return result
|
|
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument('--git-ref', help='Also check exact archive blobs and membership at this commit')
|
|
args = parser.parse_args()
|
|
manifest = read(ARCHIVE / 'manifest.json')
|
|
require(manifest['schema'] == 'closed-native440-evidence-v1', 'Unknown schema')
|
|
require((manifest['source'], manifest['oracle_source'], manifest['publication_base']) == (SOURCE, ORACLE, BASE), 'Source pins differ')
|
|
all_rows = manifest['files'] + manifest['references']
|
|
paths = [row['path'] for row in all_rows]
|
|
require(len(paths) == len(set(paths)), 'Duplicate payload/reference path')
|
|
originals = {}
|
|
for row in all_rows:
|
|
path = ROOT / row['path']
|
|
require(not Path(row['path']).is_absolute() and path.resolve().is_relative_to(ROOT), 'Escaping payload')
|
|
require(path.is_file() and not path.is_symlink(), 'Missing payload: ' + row['path'])
|
|
require(identity(path.read_bytes()) == binding(row), 'Payload bytes differ: ' + row['path'])
|
|
if 'original' in row:
|
|
require(row['original'] not in originals, 'Duplicate original mapping')
|
|
originals[row['original']] = path
|
|
own = {p.relative_to(ROOT).as_posix() for p in ARCHIVE.rglob('*') if p.is_file()}
|
|
manifest_path = (ARCHIVE / 'manifest.json').relative_to(ROOT).as_posix()
|
|
require(own == {r['path'] for r in manifest['files']} | {manifest_path}, 'Archive inventory differs')
|
|
require(all(Path(p).suffix.lower() not in ('.exe', '.dll', '.pdb', '.rlib', '.rmeta') for p in own), 'Binary/cache in archive')
|
|
for row, data in zip(manifest['references'], blobs([BASE + ':' + r['path'] for r in manifest['references']])):
|
|
require(row['commit'] == BASE and identity(data) == binding(row), 'Published reference differs')
|
|
|
|
def original(path):
|
|
key = str(path).replace('\\', '/')
|
|
if key.startswith(ORIGINAL_ROOT):
|
|
key = key[len(ORIGINAL_ROOT):]
|
|
require(key in originals, 'Original not archived/referenced: ' + key)
|
|
return originals[key]
|
|
|
|
trial = ARCHIVE / 'raw/trial'
|
|
audit = read(ARCHIVE / 'review/navigation-native-final-independent-audit-20260913.json')
|
|
evidence = [{'path': p.name, **identity(p.read_bytes())} for p in sorted((trial / 'evidence').iterdir())]
|
|
require(len(evidence) == 157 and sum(r['path'].endswith('.json') for r in evidence) == 79 and sum(r['path'].endswith('.jpg') for r in evidence) == 78, 'Evidence count differs')
|
|
require(evidence == audit['evidence'] and canonical(evidence) == '25c4ff90e456f0bd7ee33f78d8e1dee451c5e5e636fb3bff4b8fc73a35e738c2', 'Evidence map differs')
|
|
require(canonical([r for r in evidence if int(r['path'][:3]) <= 55]) == '9d52787d9c9f734e7968c299e535f7e0229499088bd6afa752fe874753f753c4', 'Original failed evidence changed')
|
|
for p in (trial / 'evidence').glob('*.json'):
|
|
note = read(p)
|
|
require(note['window']['app'].replace('\\', '/').endswith('/navigation-selection-stage-44095f7/arcadia-studio.exe'), 'Wrong screenshot application')
|
|
|
|
expected_names = {
|
|
'source': ['cancel-saved-440', 'rename-saved-440', 'undo-saved-440', 'redo-saved-440', 'reopened-saved-440', 'navigation-saved-440', 'final-source-saved-440'],
|
|
'compact': ['placement-hidden-saved-440', 'placement-undo-saved-440', 'placement-redo-saved-440', 'placement-final-undo-saved-440', 'navigation-final-saved-440'],
|
|
'lifecycle': ['navigation-saved-440'], 'topology': ['navigation-final-saved-440']}
|
|
names = {kind + '-' + label for kind, labels in expected_names.items() for label in labels}
|
|
require({p.name for p in (trial / 'checkpoints').iterdir()} == names, 'Checkpoint membership differs')
|
|
intent = read(trial / 'source-rename-expected/intent.json')
|
|
require(len(intent['edits']) == 6 and intent['target_uuid'] == '00000000-0000-4000-8000-000000000403', 'Wrong rename intent')
|
|
expected = {}
|
|
for row in intent['inputs']:
|
|
data = (trial / 'source-baseline' / row['path']).read_bytes()
|
|
require(identity(data) == binding(row), 'Rename baseline differs')
|
|
edits = sorted((e for e in intent['edits'] if e['path'] == row['path']), key=lambda e: e['start'], reverse=True)
|
|
for e in edits:
|
|
require(data[e['start']:e['end']] == e['old'].encode(), 'Wrong old rename token')
|
|
data = data[:e['start']] + e['new'].encode() + data[e['end']:]
|
|
require(data == (trial / 'source-rename-expected/expected' / row['path']).read_bytes(), 'Independent rename differs')
|
|
expected[row['path']] = identity(data)
|
|
|
|
launch = read(trial / 'launch.json')
|
|
closure = read(trial / 'closure.json')
|
|
stage = read(ARCHIVE / 'raw/stage/manifest.json')
|
|
config = read(ARCHIVE / 'raw/helpers/navigation-selection-native-final-44095f7.json')
|
|
require(launch['source'] == closure['source'] == stage['source'] == config['source'] == SOURCE, 'Native source differs')
|
|
require(launch['pid'] == closure['pid'] == 6772 and closure['exit'] == 0 and closure['stage_unchanged'] is True, 'Normal closure missing')
|
|
require(closure['utc'] == '2026-09-13T10:20:14.983254+00:00', 'Wrong trial closure')
|
|
require(identity((ARCHIVE / 'raw/stage/manifest.json').read_bytes()) == launch['stage_manifest'], 'Stage manifest binding differs')
|
|
require(identity(original('.local/navigation-palette-native-session-command-r2.py').read_bytes()) == launch['helper'], 'Launcher binding differs')
|
|
require(identity(original('.local/navigation-selection-native-final-44095f7.json').read_bytes()) == launch['config'], 'Config binding differs')
|
|
require(read(trial / 'launch-request.json').items() <= launch.items(), 'Launch request differs')
|
|
for stream in ('stdout', 'stderr'):
|
|
require(identity((trial / (stream + '.log')).read_bytes()) == closure[stream] and closure[stream]['bytes'] == 0, 'Native stream differs')
|
|
require(json.loads(original('.local/navigation-native-launch-r2-20260913.log').read_text().splitlines()[-1]) == closure, 'Supervisor closure log differs')
|
|
oracle_build = read(original(config['oracle']['build']['path']))
|
|
require(oracle_build['source'] == oracle_build['head_after'] == ORACLE and oracle_build['exit'] == 0 and oracle_build['outcome'] == 'passed', 'Oracle build failed/misbound')
|
|
require(binding(oracle_build['binary']) == binding(config['oracle']['binary']), 'Oracle binary identity differs')
|
|
omitted = {config['oracle']['binary']['path']: binding(config['oracle']['binary']),
|
|
'.local/toolchain/llvm-mingw-20260908-ucrt-x86_64/bin/libunwind.dll': binding(config['runtime'])}
|
|
for name in sorted(names):
|
|
folder = trial / 'checkpoints' / name
|
|
cp = read(folder / 'checkpoint.json')
|
|
actual = inventory(folder / 'tree')
|
|
baseline = inventory(trial / (cp['fixture'] + '-baseline'))
|
|
require(cp['status'] == 'PASS' and cp['inputs_unchanged'] is True, 'Checkpoint failed: ' + name)
|
|
require(all(cp[k] == actual for k in ('before', 'copy', 'after', 'final_work', 'final_copy')), 'Snapshot inventory mismatch')
|
|
require(cp['baseline_before'] == cp['final_baseline'] == baseline, 'Baseline inventory mismatch')
|
|
for path, wanted in cp['watched_inputs'].items():
|
|
require(identity(original(path).read_bytes()) == binding(wanted), 'Watched input differs')
|
|
require(identity(original('.local/checkpoint-navigation-palette-20260913.py').read_bytes()) == cp['helper'], 'Checkpoint helper differs')
|
|
run = read(folder / 'oracle-run.json')
|
|
require((folder / 'oracle-run.json').read_bytes() == (trial / ('checkpoint-' + name) / 'run.json').read_bytes(), 'Copied run differs')
|
|
require(identity((folder / 'oracle-run.json').read_bytes()) == cp['oracle']['receipt'], 'Run receipt binding differs')
|
|
require(cp['oracle']['exit'] == run['exit'] == 0 and run['outcome'] == 'passed' and run['failure'] is None and run['inputs_unchanged'] is True and run['changed_inputs'] == [], 'Oracle failed')
|
|
require(run['source'] == ORACLE and run['verified_core_inputs'] == 111, 'Oracle source scope differs')
|
|
require(run['command'][1] == cp['mode'] and original(run['command'][2]).parent == trial / (cp['fixture'] + '-baseline') and original(run['command'][3]).parent == folder / 'tree', 'Oracle mode/entries differ')
|
|
for path, wanted in run['inputs_before'].items():
|
|
key = path.replace('\\', '/').removeprefix(ORIGINAL_ROOT)
|
|
if key in omitted:
|
|
require(binding(wanted) == omitted[key], 'Omitted binary binding differs')
|
|
else:
|
|
require(identity(original(path).read_bytes()) == binding(wanted), 'Oracle input differs')
|
|
for stream in ('stdout', 'stderr'):
|
|
require(identity(original(run[stream]['path']).read_bytes()) == binding(run[stream]), 'Oracle raw stream differs')
|
|
require(all(line.startswith('Permitted non-error diagnostic in ') for line in original(run['stderr']['path']).read_text().splitlines()), 'Unexpected oracle diagnostic')
|
|
if cp['mode'] == 'same':
|
|
require(actual == baseline and cp['exact_baseline_bytes'] is True, 'Same-mode bytes differ')
|
|
elif cp['mode'] == 'renamed':
|
|
require(actual['files'] == expected and run['command'][4:] == ['00000000-0000-4000-8000-000000000403', 'assess_report_union'], 'Renamed expectation differs')
|
|
elif cp['mode'] == 'removed':
|
|
require(run['command'][4:] == ['de1e7e00-0000-4000-8000-000000000029'], 'Wrong removal UUID')
|
|
else:
|
|
require(False, 'Unexpected checkpoint mode')
|
|
|
|
for key, row in config['build'].items():
|
|
require(identity(original(row['path']).read_bytes()) == binding(row), 'Build raw binding differs: ' + key)
|
|
build = read(original(config['build']['result']['path']))
|
|
require(build['source'] == build['head_after'] == SOURCE and build['exit'] == 0 and build['outcome'] == 'passed' and build['failure'] is None and build['changed_inputs'] == [], 'Original build failed/misbound')
|
|
records = [json.loads(line) for line in original(config['build']['stdout']['path']).read_text().splitlines()]
|
|
require(any(row.get('reason') == 'build-finished' and row.get('success') is True for row in records), 'No successful build-finished record')
|
|
for artifact in build['artifacts']:
|
|
require(artifact['cargo_artifact'] in records and binding(artifact) == stage['payloads'][artifact['name'] + '.exe'], 'Cargo/stage artifact differs')
|
|
require(artifact['cargo_artifact']['profile'] == {'opt_level': '0', 'debuginfo': 0, 'debug_assertions': True, 'overflow_checks': True, 'test': False}, 'Build profile differs')
|
|
require(stage['payloads']['arcadia-studio.exe'] == launch['gui'] and stage['payloads']['libunwind.dll'] == launch['runtime'] and stage['profile'] == 'unoptimized development', 'Launch/profile differs')
|
|
inputs = read(original(config['build']['inputs']['path']))
|
|
require(inputs['source'] == SOURCE and len(inputs['inputs']) == 615, 'Wrong build inputs')
|
|
captured = {row['path']: binding(row) for row in inputs['inputs']}
|
|
require(len(captured) == 615, 'Duplicate build input')
|
|
for pin in (SOURCE, BASE):
|
|
for path, data in zip(captured, blobs([pin + ':' + p for p in captured])):
|
|
require(identity(data) == captured[path], 'Source Git bytes differ: ' + pin + ':' + path)
|
|
def core(rows):
|
|
return {r['path']: binding(r) for r in rows if r['path'].startswith(('crates/oa-core/', '.cargo/')) or r['path'] in ('Cargo.toml', 'Cargo.lock', 'rust-toolchain.toml')}
|
|
old = read(original('.local/navigation-palette-gates-20260913/list-e124029.inputs.json'))
|
|
equivalent = core(old['inputs'])
|
|
require(equivalent == core(inputs['inputs']) and len(equivalent) == 111, 'Oracle/440 core equivalence differs')
|
|
for path, data in zip(equivalent, blobs([ORACLE + ':' + p for p in equivalent])):
|
|
require(identity(data) == equivalent[path], 'Oracle Git source differs')
|
|
for name in names:
|
|
require({r['path']: binding(r) for r in read(trial / ('checkpoint-' + name) / 'verified-core-inputs.json')} == equivalent, 'Run core snapshot differs')
|
|
if args.git_ref:
|
|
own_paths = sorted(own)
|
|
for path, data in zip(own_paths, blobs([args.git_ref + ':' + p for p in own_paths])):
|
|
require((ROOT / path).read_bytes() == data, 'Archive Git bytes differ: ' + path)
|
|
tree = subprocess.check_output(['git', '-c', 'core.longpaths=true', 'ls-tree', '-r', '--name-only', args.git_ref, '--', ARCHIVE.relative_to(ROOT).as_posix()], cwd=ROOT).decode().splitlines()
|
|
require(set(tree) == own, 'Committed archive membership differs')
|
|
print(json.dumps({'payload_files': len(manifest['files']), 'published_references': len(manifest['references']),
|
|
'notes': 79, 'images': 78, 'checkpoints': 14, 'source_inputs': 615, 'equivalent_oracle_inputs': 111,
|
|
'source': SOURCE, 'oracle_source': ORACLE, 'closure_exit': closure['exit'], 'git_ref': args.git_ref,
|
|
'manifest_sha256': identity((ARCHIVE / 'manifest.json').read_bytes())['sha256'],
|
|
'scope': 'Portable byte/receipt/Git verification only. Known scroll FAIL preserved; no feature/package acceptance.'}, indent=2))
|