Files
ARCADIA-Studio/harness/experiments/navigation-native-440-20260913/raw/helpers/navigation-palette-native-session-command-r2.py
T

459 lines
29 KiB
Python

"""Prepare/check a same-source native stage; launch only on explicit launch command.
No compiler or application is run by check/stage. Config contains pins to actual
receipts, never configurable success predicates. Parent reviews the final config.
"""
from pathlib import Path
from datetime import datetime, timezone
import argparse
import hashlib
import json
import os
import re
import subprocess
import sys
ROOT = Path(__file__).resolve().parent.parent
TRIAL = ROOT / '.local/native-qa/navigation-palette-20260913-01'
RUNTIME = 'aa282fa47bb2c4e210cea5e470cdbdca58568f0be0bc73e404d86ab9cd95ef6a'
SCOPES = ['Cargo.toml', 'Cargo.lock', 'rust-toolchain.toml', '.cargo', 'build',
'crates', 'assets', 'docs', 'examples', 'harness/fixtures']
PREFIX = ['cargo', 'test', '--locked', '-p', 'oa-desktop', '--bin', 'arcadia-studio']
def require(condition, message):
if not condition:
raise ValueError(message)
def now():
return datetime.now(timezone.utc).isoformat()
def identity(raw):
return {'bytes': len(raw), 'sha256': hashlib.sha256(raw).hexdigest()}
def rooted(name):
require(isinstance(name, str) and name, 'Pending/missing path')
path = Path(name)
if not path.is_absolute():
path = ROOT / path
resolved = path.resolve()
require(resolved.is_relative_to(ROOT), 'Evidence/output must stay in this checkout: ' + name)
current = path.absolute()
while current != ROOT and current.is_relative_to(ROOT):
require(not current.is_symlink() and not current.is_junction(), 'Reparse evidence path: ' + str(current))
current = current.parent
return resolved
def write_new(path, raw):
with path.open('xb') as stream:
stream.write(raw)
def save(path, value):
write_new(path, (json.dumps(value, indent=2) + '\n').encode('utf-8'))
def command(record):
result = list(record['command'])
require(result, 'Empty recorded command')
result[0] = Path(result[0]).name.casefold().removesuffix('.exe')
return result
def preflight(config_path, source):
require(re.fullmatch('[0-9a-f]{40}', source), 'Exact final source SHA required')
config_path = rooted(str(config_path))
config_raw = config_path.read_bytes()
cfg = json.loads(config_raw)
require(cfg['schema'] == 1 and cfg['source'] == source, 'Pending or different configured source')
stage = rooted(cfg['stage'])
require(stage.is_relative_to(ROOT / '.local/native-qa') and not stage.is_relative_to(TRIAL)
and not TRIAL.is_relative_to(stage), 'Use a separate new stage under .local/native-qa')
pins = {}
def pin(item):
require(isinstance(item, dict) and isinstance(item.get('bytes'), int)
and re.fullmatch('[0-9a-f]{64}', item.get('sha256') or ''), 'Pending/invalid evidence pin')
path = rooted(item['path'])
raw = path.read_bytes()
require(identity(raw) == {key: item[key] for key in ('bytes', 'sha256')}, 'Changed evidence: ' + str(path))
pins[str(path)] = identity(raw)
return raw
def document(item):
return json.loads(pin(item))
# Require exact complete raw committed build/gate membership, not clean status alone.
manifests = []
gates = {}
for mode in ('listing', 'focused', 'scroll', 'full', 'strict'):
spec = cfg['gates'][mode]
record = document(spec['result'])
inputs = document(spec['inputs'])
log = pin(spec['log']).decode('utf-8', errors='strict')
require(record['source'] == record['head_after'] == inputs['source'] == source
and record['exit'] == 0 and record['changed_inputs'] == [], 'Gate did not pass unchanged at final source: ' + mode)
require(rooted(spec['inputs']['path']) == rooted(spec['result']['path']).parent / record['inputs'], 'Gate input-manifest path mismatch')
manifests.append((inputs['inputs'], SCOPES))
wanted = {
'listing': PREFIX + ['--', '--list'],
'focused': PREFIX + ['navigation_union', '--', '--test-threads=1'],
'scroll': PREFIX + ['preview_scroll_tests', '--', '--test-threads=1'],
'full': PREFIX + ['--', '--test-threads=1'],
'strict': ['cargo', 'clippy', '--locked', '-p', 'oa-desktop', '--all-targets', '--', '-D', 'warnings'],
}[mode]
require(command(record) == wanted, 'Unexpected actual gate command: ' + mode)
if mode != 'strict':
require(len(record['artifacts']) == 1, 'Gate requires its actual test executable')
pin(record['artifacts'][0])
gates[mode] = (spec, record, log)
listing = gates['listing'][1]
names = re.findall(r'^([^\r\n]+): test\r?$', gates['listing'][2], re.M)
require(names and len(names) == len(set(names)) and names == listing['listing_members']
and len(names) == listing['listing_count'], 'Exact actual listing mismatch')
require(re.findall(r'^(\d+) tests, (\d+) benchmarks\s*$', gates['listing'][2], re.M)
== [(str(len(names)), '0')], 'Listing summary mismatch')
required = document(cfg['required_names'])['groups']
for key, count in [('navigation_union', 17), ('preview_scroll_tests', 4)]:
selected = {name for name in names if key in name}
require(len(selected) == count and selected == set(required[key])
and len(required[key]) == count, 'Required exact membership mismatch: ' + key)
required_all = set()
for key, members in required.items():
require(len(members) == len(set(members)) and set(members).issubset(names), 'Unlisted/duplicate required tests: ' + key)
required_all.update(members)
for mode in ('listing', 'focused', 'scroll'):
spec, record, log = gates[mode]
admitted = document(spec['admission'])
require(admitted['source'] == source and admitted['mode'] == ('list' if mode == 'listing' else 'focused')
and admitted['result_sha256'] == spec['result']['sha256']
and admitted['log_sha256'] == spec['log']['sha256']
and admitted['inputs_sha256'] == spec['inputs']['sha256']
and admitted['required_names_sha256'] == cfg['required_names']['sha256']
and admitted['artifact'] == record['artifacts'][0] == listing['artifacts'][0], 'Admission does not bind actual gate: ' + mode)
if mode != 'listing':
selector = 'navigation_union' if mode == 'focused' else 'preview_scroll_tests'
actual = re.findall(r'^test ([^\r\n]+) \.\.\. ok\s*$', log, re.M)
require(len(actual) == len(set(actual)) and set(actual) == set(required[selector]), 'Focused executed membership differs')
require(re.findall(r'test result: ok\. (\d+) passed; (\d+) failed; (\d+) ignored;', log)
== [(str(len(actual)), '0', '0')], 'Focused summary differs')
full = gates['full']
require(full[1]['artifacts'][0] == listing['artifacts'][0], 'Full/list test executable differs')
full_cases = re.findall(r'^test ([^\r\n]+) \.\.\. (ok|ignored)(?:, [^\r\n]*)?\s*$', full[2], re.M)
require(len(full_cases) == len(names) and len({name for name, _ in full_cases}) == len(names)
and {name for name, _ in full_cases} == set(names), 'Full executed membership differs from listing')
ignored = {name for name, status in full_cases if status == 'ignored'}
require(isinstance(cfg['approved_full_ignored'], list) and ignored == set(cfg['approved_full_ignored'])
and not (ignored & required_all), 'Unapproved ignored/full required test')
require(re.findall(r'test result: ok\. (\d+) passed; (\d+) failed; (\d+) ignored;', full[2])
== [(str(len(names) - len(ignored)), '0', str(len(ignored)))], 'Full summary differs')
build_cfg = cfg['build']
build = document(build_cfg['result'])
build_inputs = document(build_cfg['inputs'])
environment = document(build_cfg['environment'])
cargo_raw = pin(build_cfg['stdout'])
pin(build_cfg['stderr'])
require(build['source'] == build['head_after'] == build_inputs['source'] == source
and build['outcome'] == 'passed' and build['exit'] == 0 and build['failure'] is None
and build['changed_inputs'] == [] and build['status_after'] == '', 'Both-artifact build not completed unchanged')
require(command(build) == ['cargo', 'build', '--locked', '--offline', '-p', 'oa-desktop', '-p', 'oa-server', '--bins', '--message-format=json-render-diagnostics'], 'Wrong artifact build command')
for key in ('inputs', 'environment', 'stdout', 'stderr'):
require(build[key] == {field: build_cfg[key][field] for field in ('bytes', 'sha256')}, 'Build receipt/log binding differs: ' + key)
require('host: x86_64-pc-windows-gnullvm' in environment['tools']['rustc']['version'], 'Wrong recorded Rust host')
manifests.append((build_inputs['inputs'], SCOPES + ['scripts']))
messages = [json.loads(line) for line in cargo_raw.splitlines()]
require([m for m in messages if m.get('reason') == 'build-finished'] == [{'reason': 'build-finished', 'success': True}], 'Actual Cargo finish not unique/successful')
selected = [m for m in messages if m.get('reason') == 'compiler-artifact' and m.get('executable')
and m.get('target', {}).get('name') in ('arcadia-studio', 'arcadia-server') and m['target']['kind'] == ['bin']]
require(len(selected) == len(build['artifacts']) == 2, 'Two actual preserved binary records required')
payloads = {}
for artifact in build['artifacts']:
name = artifact['name']
require(name in ('arcadia-studio', 'arcadia-server') and name + '.exe' not in payloads, 'Duplicate/wrong artifact')
require(artifact['cargo_artifact'] in selected, 'Preserved artifact not emitted by Cargo')
profile = artifact['cargo_artifact']['profile']
require(profile['opt_level'] == '0' and profile['debug_assertions'] and not profile['test'], 'Expected actual development profile')
require(rooted(artifact['cargo_artifact']['executable']) == rooted(artifact['origin']), 'Cargo artifact origin mismatch')
item = {'path': artifact['preserved'], **{key: artifact[key] for key in ('bytes', 'sha256')}}
raw = pin(item)
require(raw[:2] == b'MZ' and len(raw) >= 64, 'Not PE executable')
pe = int.from_bytes(raw[60:64], 'little')
require(raw[pe:pe+4] == b'PE\0\0' and int.from_bytes(raw[pe+4:pe+6], 'little') == 0x8664, 'Not Windows x64 PE')
payloads[name + '.exe'] = item
require(cfg['runtime']['sha256'] == RUNTIME, 'Only the reviewed September runtime is admitted')
pin(cfg['runtime'])
payloads['libunwind.dll'] = cfg['runtime']
all_inputs = {}
for rows, scopes in manifests:
expected = subprocess.check_output(['git', 'ls-tree', '-r', '--name-only', source, *scopes], cwd=ROOT).decode().splitlines()
require(len(rows) == len(expected) and {row['path'] for row in rows} == set(expected), 'Incomplete committed input membership')
for row in rows:
if row['path'] in all_inputs:
require(all_inputs[row['path']] == row, 'Gate/build input identity differs')
all_inputs[row['path']] = row
ordered = sorted(all_inputs)
blobs = subprocess.check_output(['git', 'cat-file', '--batch'], cwd=ROOT,
input=''.join(source + ':' + path + '\n' for path in ordered).encode())
offset = 0
for path in ordered:
end = blobs.index(b'\n', offset)
_, kind, size = blobs[offset:end].split()
require(kind == b'blob', 'Missing committed blob')
size = int(size)
raw = blobs[end+1:end+1+size]
require(blobs[end+1+size:end+2+size] == b'\n', 'Bad Git blob framing')
offset = end+2+size
require(identity(raw) == {key: all_inputs[path][key] for key in ('bytes', 'sha256')}, 'Raw Git input mismatch: ' + path)
require(pin(all_inputs[path]) == raw, 'Current input differs: ' + path)
if path.startswith(('docs/', 'examples/')):
payloads[path] = all_inputs[path]
require(offset == len(blobs), 'Extra Git response')
oracle = cfg['oracle']
oracle_build = document(oracle['build'])
oracle_source = oracle['build_source']
require(re.fullmatch('[0-9a-f]{40}', oracle_source or '')
and oracle_build['source'] == oracle_build['head_after'] == oracle_source
and oracle_build['exit'] == 0 and oracle_build['outcome'] == 'passed'
and oracle_build['failure'] is None and oracle_build['changed_inputs'] == []
and oracle_build['status_after'] == '', 'Oracle build did not pass unchanged at its declared source')
build_dir = rooted(oracle['build']['path']).parent
for name in ('stdout', 'stderr'):
pin({'path': str(build_dir / (name + '.log')), **oracle_build[name]})
captured = {rooted(path): item for path, item in oracle_build['inputs_before'].items()}
require(len(captured) == len(oracle_build['inputs_before']), 'Duplicate captured oracle input')
build_launcher = rooted(oracle['build_launcher']['path'])
pin(oracle['build_launcher'])
require(captured[build_launcher] == oracle_build['launcher']
== {key: oracle['build_launcher'][key] for key in ('bytes', 'sha256')}, 'Oracle build launcher differs')
pin(oracle['source'])
require(str(rooted(oracle['source']['path'])) in oracle_build['command']
and captured[rooted(oracle['source']['path'])]
== {key: oracle['source'][key] for key in ('bytes', 'sha256')}, 'Reviewed oracle source not build-bound')
require(oracle_build['source_inputs'], 'Missing preserved oracle compilation inputs')
for item in oracle_build['source_inputs']:
require(captured[rooted(item['path'])] == {key: item[key] for key in ('bytes', 'sha256')}, 'Preserved source identity differs')
pin({'path': item['preserved'], **captured[rooted(item['path'])]})
binary = rooted(oracle['binary']['path'])
pin(oracle['binary'])
require(rooted(oracle_build['binary']['path']) == binary and oracle_build['binary']['sha256'] == oracle['binary']['sha256']
and oracle_build['binary']['bytes'] == oracle['binary']['bytes'], 'Oracle executable not build-bound')
require(oracle_build['command'][-2:] == ['-o', str(binary)], 'Oracle build output differs')
# Compare the FINAL test anchor with captured dependency identities. The old
# desktop test executable/anchor may have been overwritten by a desktop fix.
anchor = document(oracle['final_anchor'])
test_exe = rooted(listing['artifacts'][0]['path'])
suffix = test_exe.stem.removeprefix('arcadia_studio-').removeprefix('arcadia-studio-')
require(rooted(oracle['final_anchor']['path']) == test_exe.parent.parent / '.fingerprint' / ('oa-desktop-' + suffix) / 'test-bin-arcadia-studio.json', 'Final oracle anchor not admitted test executable fingerprint')
require(set(oracle['dependencies']) == {'oa_core', 'serde_json'}, 'Exact oracle dependency pair required')
for name, binding in oracle['dependencies'].items():
rlib = rooted(binding['rlib']['path'])
fingerprint_path = rooted(binding['fingerprint']['path'])
require(fingerprint_path.name == 'lib-' + name and fingerprint_path.parent.parent == test_exe.parent.parent / '.fingerprint'
and rlib == test_exe.parent / ('lib' + name + '-' + fingerprint_path.parent.name.rsplit('-', 1)[1] + '.rlib'), 'Fingerprint/rlib paths do not correspond')
fingerprint = pin(binding['fingerprint']).decode().strip()
pin(binding['rlib'])
fingerprint_json = rooted(binding['fingerprint_json']['path'])
require(fingerprint_json == fingerprint_path.with_name(fingerprint_path.name + '.json'), 'Dependency fingerprint JSON path differs')
pin(binding['fingerprint_json'])
expected = [row[3] for row in anchor['deps'] if row[1] == name]
require(expected == [int.from_bytes(bytes.fromhex(fingerprint), 'little')], 'Dependency does not match admitted core fingerprint: ' + name)
linked = [arg.split('=', 1)[1] for index, arg in enumerate(oracle_build['command'])
if index and oracle_build['command'][index - 1] == '--extern' and arg.startswith(name + '=')]
require(len(linked) == 1, 'Oracle command dependency not unique: ' + name)
old_rlib = rooted(linked[0])
old_suffix = old_rlib.stem.rsplit('-', 1)[1]
old_fingerprints = [path for path in captured if path.name == 'lib-' + name and path.parent.name.endswith('-' + old_suffix)]
require(len(old_fingerprints) == 1, 'Captured dependency fingerprint not unique: ' + name)
old_fp = old_fingerprints[0]
for item, old_path in ((binding['rlib'], old_rlib), (binding['fingerprint'], old_fp),
(binding['fingerprint_json'], old_fp.with_name(old_fp.name + '.json'))):
require(captured[old_path] == {key: item[key] for key in ('bytes', 'sha256')}, 'Final dependency differs from captured oracle bytes: ' + name)
captured_manifests = [path for path in captured if path.name.endswith('.inputs.json')]
require(len(captured_manifests) == 1, 'Captured oracle listing-input manifest not unique')
captured_manifest = captured_manifests[0]
old_inputs = document({'path': str(captured_manifest), **captured[captured_manifest]})
require(old_inputs['source'] == oracle_source, 'Captured listing source differs from oracle build source')
def core_scope(path):
return path.startswith(('crates/oa-core/', '.cargo/')) or path in ('Cargo.toml', 'Cargo.lock', 'rust-toolchain.toml')
scoped_rows = [row for row in old_inputs['inputs'] if core_scope(row['path'])]
captured_core = {row['path']: {key: row[key] for key in ('bytes', 'sha256')} for row in scoped_rows}
final_core = {path: {key: row[key] for key in ('bytes', 'sha256')} for path, row in all_inputs.items() if core_scope(path)}
require(len(captured_core) == len(scoped_rows) and captured_core == final_core,
'Final complete core/config raw inputs differ from captured oracle scope')
runtime_launcher = rooted(oracle['run_launcher']['path'])
pin(oracle['run_launcher'])
def oracle_run(spec, arguments):
run = document(spec['receipt'])
run_dir = rooted(spec['receipt']['path']).parent
require(run['source'] == oracle_source and run['exit'] == 0 and run['outcome'] == 'passed'
and run['failure'] is None and run['changed_inputs'] == [] and run['inputs_unchanged'] is True
and run['oracle_sha256'] == oracle['binary']['sha256']
and run['command'] == [str(binary), *arguments], 'Actual oracle run failed/differs')
require(rooted(run['build']['path']) == rooted(oracle['build']['path'])
and {key: run['build'][key] for key in ('bytes', 'sha256')}
== {key: oracle['build'][key] for key in ('bytes', 'sha256')}, 'Run does not bind selected oracle build')
require(run['launcher'] == {key: oracle['run_launcher'][key] for key in ('bytes', 'sha256')}, 'Run launcher differs')
for name in ('stdout', 'stderr'):
require(rooted(run[name]['path']) == run_dir / (name + '.log'), 'Run log location differs')
pin(run[name])
verified = document(spec['verified_core_inputs'])
require(rooted(spec['verified_core_inputs']['path']) == run_dir / 'verified-core-inputs.json'
and verified == scoped_rows and run['verified_core_inputs'] == len(scoped_rows), 'Run core-input evidence differs')
watched = {rooted(path): item for path, item in run['inputs_before'].items()}
expected_paths = {binary, rooted(oracle['build']['path']), captured_manifest}
runtimes = [path for path in watched if path.name == 'libunwind.dll']
require(len(runtimes) == 1 and watched[runtimes[0]] == {key: cfg['runtime'][key] for key in ('bytes', 'sha256')}, 'Run runtime differs')
expected_paths.add(runtimes[0])
expected_folders = [] if arguments == ['self-check'] else [rooted(arg).parent for arg in arguments[1:3]]
require([rooted(tree['folder']) for tree in run['input_trees']] == expected_folders, 'Run fixture tree roots differ')
for tree in run['input_trees']:
folder = rooted(tree['folder'])
actual = {path.resolve() for path in folder.rglob('*') if path.is_file()}
require(len(tree['paths']) == len(actual) and {rooted(path) for path in tree['paths']} == actual, 'Run fixture tree membership changed')
expected_paths.update(actual)
require(len(watched) == len(run['inputs_before']) and set(watched) == expected_paths, 'Run watched input membership differs')
for path, item in watched.items():
pin({'path': str(path), **item})
oracle_run(oracle['self_check'], ['self-check'])
preparation = document(cfg['fixture_preparation'])
require(rooted(cfg['fixture_preparation']['path']) == TRIAL / 'preparation.json', 'Original trial preparation required')
provenance = rooted(preparation['provenance_manifest']['path'])
provenance_raw = provenance.read_bytes()
require(identity(provenance_raw)['sha256'] == preparation['provenance_manifest']['sha256'], 'Original fixture archive provenance changed')
pins[str(provenance)] = identity(provenance_raw)
prepared_paths = set()
for row in preparation['files']:
item = {**row, 'path': str(TRIAL / row['path'])}
require(pin(item) == rooted(row['source']).read_bytes(), 'Prepared original fixture differs')
prepared_paths.add(rooted(item['path']))
migration = document(cfg['migration']['result'])
intent = document(cfg['migration']['intent'])
require(migration['status'] == 'PASS' and (migration['from_schema'], migration['to_schema']) == (3, 7)
and migration['independent_full_project_equal'] is True and migration['current_readmission_exact'] is True
and migration['originals_preserved'] is True and migration['alias_tokens'] == 6 and migration['alias_files'] == 2,
'Actual separate fixture migration not admitted')
require((intent['from_schema'], intent['to_schema']) == (3, 7) and intent['execution_complete'] is False,
'Preserve the original pending migration intent, not a rewritten success claim')
require(cfg['fixture_evidence'], 'Pending fixture/migration evidence')
for item in cfg['fixture_evidence']:
pin(item)
require(len(cfg['fixture_pairs']) >= 3, 'Prepared fixture admissions missing')
covered, pairs = set(), set()
for pair in cfg['fixture_pairs']:
require(pair['files'], 'Empty fixture pair inventory')
inventory_paths = set()
for item in pair['files']:
path = rooted(item['path'])
require(path.is_relative_to(TRIAL), 'Fixture outside trial')
pin(item)
inventory_paths.add(path)
baseline, work = rooted(pair['baseline_entry']), rooted(pair['work_entry'])
require(baseline in inventory_paths and work in inventory_paths and baseline != work, 'Pair entries not distinct inventoried fixtures')
# Require complete directory membership, not just a declared subset.
actual_paths = {p.resolve() for directory in (baseline.parent, work.parent) for p in directory.rglob('*') if p.is_file()}
require(actual_paths == inventory_paths, 'Fixture pair has unlisted/missing files')
require((baseline, work) not in pairs, 'Duplicate fixture admission')
pairs.add((baseline, work))
covered.update(inventory_paths)
oracle_run(pair['admission'], ['same', str(baseline), str(work)])
require(prepared_paths.issubset(covered), 'An original prepared fixture has no current-core admission')
migrated_base = rooted(cfg['migration']['baseline_entry'])
require(any(base == migrated_base for base, _ in pairs), 'Migrated source-project baseline lacks current-core admission')
return cfg, stage, payloads, {'source': source, 'config_path': str(config_path), 'config': identity(config_raw),
'helper': identity(Path(__file__).read_bytes()), 'evidence': pins,
'oracle_source': oracle_source, 'oracle_binary': oracle['binary'], 'oracle_core_inputs': len(captured_core),
'listing_count': len(names), 'full_passed': len(names) - len(ignored), 'full_ignored': sorted(ignored),
'profile': 'unoptimized development', 'scope': 'Identified native stage admission only; native acceptance pending'}
def stage_map(stage):
result = {}
for path in stage.rglob('*'):
require(not path.is_symlink() and not path.is_junction(), 'Reparse stage input')
if path.is_file() and path != stage / 'manifest.json':
result[path.relative_to(stage).as_posix()] = identity(path.read_bytes())
return result
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('mode', choices=('check', 'stage', 'launch'))
parser.add_argument('config', type=Path)
parser.add_argument('source')
args = parser.parse_args()
cfg, stage, payloads, attestation = preflight(args.config.resolve(), args.source)
if args.mode == 'check':
print(json.dumps({'evidence_admitted': True, 'ready_for_stage': not stage.exists(), **attestation}, indent=2))
return
if args.mode == 'stage':
stage.mkdir(exist_ok=False)
for name, item in payloads.items():
path = stage / name
path.parent.mkdir(parents=True, exist_ok=True)
raw = rooted(item['path']).read_bytes()
require(identity(raw) == {key: item[key] for key in ('bytes', 'sha256')}, 'Input changed during staging')
write_new(path, raw)
copied = stage_map(stage)
require(copied == {name: {key: item[key] for key in ('bytes', 'sha256')} for name, item in payloads.items()}, 'Staged copies differ from selected inputs')
manifest = {**attestation, 'created': now(), 'payloads': copied}
save(stage / 'manifest.json', manifest)
print(json.dumps({'stage': str(stage), 'manifest': identity((stage / 'manifest.json').read_bytes())}))
return
manifest_raw = (stage / 'manifest.json').read_bytes()
manifest = json.loads(manifest_raw)
require(all(manifest[key] == attestation[key] for key in attestation), 'Stage admission/config no longer matches')
require(stage_map(stage) == manifest['payloads'], 'Stage membership/bytes changed')
for name in ('launch-request.json', 'launch.json', 'closure.json', 'stdout.log', 'stderr.log', 'supervisor-error.json', 'profile', 'temp', 'working-directory'):
require(not (TRIAL / name).exists(), 'Trial launch already attempted: ' + name)
profile, temporary, cwd = TRIAL / 'profile', TRIAL / 'temp', TRIAL / 'working-directory'
profile.mkdir(); temporary.mkdir(); cwd.mkdir()
for path in (profile / 'AppData/Local', profile / 'AppData/Roaming'):
path.mkdir(parents=True)
windows = Path(os.environ['SystemRoot'])
env = {key: os.environ[key] for key in ('SystemRoot', 'WINDIR', 'SystemDrive', 'ProgramData', 'ALLUSERSPROFILE', 'PUBLIC', 'COMSPEC', 'PATHEXT', 'NUMBER_OF_PROCESSORS', 'PROCESSOR_ARCHITECTURE', 'OS') if key in os.environ}
env.update(PATH=os.pathsep.join(map(str, (stage, windows / 'System32', windows))),
USERPROFILE=str(profile), HOMEDRIVE=profile.drive, HOMEPATH=str(profile)[len(profile.drive):],
LOCALAPPDATA=str(profile / 'AppData/Local'), APPDATA=str(profile / 'AppData/Roaming'), TEMP=str(temporary), TMP=str(temporary))
invocation = [str(stage / 'arcadia-studio.exe')]
request = {'utc': now(), 'source': args.source, 'command': invocation, 'cwd': str(cwd), 'environment': env,
'stage_manifest': identity(manifest_raw), 'config': attestation['config'], 'helper': attestation['helper']}
save(TRIAL / 'launch-request.json', request)
process = None
try:
with (TRIAL / 'stdout.log').open('xb') as stdout, (TRIAL / 'stderr.log').open('xb') as stderr:
process = subprocess.Popen(invocation, cwd=cwd, env=env, stdin=subprocess.DEVNULL,
stdout=stdout, stderr=stderr, creationflags=subprocess.CREATE_NO_WINDOW)
launch = {**request, 'pid': process.pid, 'spawned_utc': now(), 'gui': manifest['payloads']['arcadia-studio.exe'], 'runtime': manifest['payloads']['libunwind.dll']}
save(TRIAL / 'launch.json', launch)
print(json.dumps(launch), flush=True)
code = process.wait()
unchanged = stage_map(stage) == manifest['payloads'] and (stage / 'manifest.json').read_bytes() == manifest_raw
closure = {'utc': now(), 'source': args.source, 'pid': process.pid, 'exit': code,
'stage_unchanged': unchanged, 'stdout': identity((TRIAL / 'stdout.log').read_bytes()),
'stderr': identity((TRIAL / 'stderr.log').read_bytes()), 'scope': 'Observed owned-process closure; not automatic native acceptance'}
save(TRIAL / 'closure.json', closure)
print(json.dumps(closure), flush=True)
raise SystemExit(code if code else (0 if unchanged else 1))
except (Exception, KeyboardInterrupt) as error:
save(TRIAL / 'supervisor-error.json', {'utc': now(), 'error': repr(error),
'pid': None if process is None else process.pid,
'observed_exit': None if process is None else process.poll(),
'scope': 'Supervisor failure; no invented normal closure and no unrelated process cleanup'})
raise
if __name__ == '__main__':
main()