Files
ARCADIA-Studio/harness/experiments/canvas-native-d61f1f3-20260912/tools/archive-canvas-native-d61f1f3.py
T

156 lines
7.5 KiB
Python

"""Archive only the closed, identified canvas native trial; never stage/commit."""
from pathlib import Path
from datetime import datetime, timezone
import hashlib
import json
root = Path(__file__).resolve().parent.parent
trial = root / '.local/native-qa/canvas-paint-d61f1f3-20260912-01'
stage = root / '.local/native-qa/studio-d61f1f3'
prefix = 'harness/experiments/canvas-native-d61f1f3-20260912'
destination = root / prefix
source = 'd61f1f38779ab70a77efcde523ae31c432aefcfd'
result_path = root / '.local/canvas-native-d61f1f3-archive-result.json'
assert not destination.exists() and not result_path.exists(), 'Never overwrite an archive/run'
assert destination.resolve().is_relative_to(root / 'harness/experiments')
def digest(path):
raw = path.read_bytes()
return {'bytes': len(raw), 'sha256': hashlib.sha256(raw).hexdigest()}
def read(path):
return json.loads(path.read_bytes())
def verify(path, record):
actual = digest(path)
assert actual['sha256'] == record['sha256'], str(path)
if 'bytes' in record:
assert actual['bytes'] == record['bytes'], str(path)
def write_new(path, record):
with path.open('x', encoding='utf-8', newline='\n') as stream:
stream.write(json.dumps(record, indent=2) + '\n')
launch = read(trial / 'launch.json')
closure = read(trial / 'closure.json')
prepared = read(trial / 'preparation.json')
staged = read(stage / 'manifest.json')
assert launch['source'] == staged['source'] == staged['full_test_source'] == source
assert closure['pid'] == launch['pid'] and closure['exit'] == 0
assert prepared['utc'] < launch['utc'] < closure['utc']
assert Path(launch['binary']).resolve() == (stage / 'arcadia-studio.exe').resolve()
assert launch['sha256'] == staged['artifacts']['arcadia-studio.exe']['sha256']
for name in ['arcadia-studio.exe', 'libunwind.dll']:
verify(stage / name, staged['artifacts'][name])
for name in ['full', 'clippy', 'gui']:
gate = staged['results'][name]
assert gate['source'] == source and gate['exit'] == 0 and not gate['changed_inputs']
baseline_names = ['bound-baseline']
baseline_records = [row for row in prepared['files'] if Path(row['path']).parts[0] in baseline_names]
for row in baseline_records:
verify(trial / row['path'], row)
# Original baseline sources are independently retained elsewhere too.
verify(root / row['source'], row)
assert {row['path'] for row in baseline_records} == {
path.relative_to(trial).as_posix() for name in baseline_names
for path in (trial / name).rglob('*') if path.is_file()}
checkpoint_records = []
checkpoint_files = set()
oracle_identities = {}
for path in sorted((trial / 'evidence').glob('*.json')):
record = read(path)
assert set(['snapshot', 'command', 'checker_sha256', 'exit', 'files']) <= record.keys(), str(path)
assert record['exit'] == 0
snapshot = Path(record['snapshot']).resolve()
assert snapshot == (trial / 'checkpoints' / path.stem).resolve()
assert record['utc'] <= closure['utc']
actual = {p.resolve() for p in snapshot.rglob('*') if p.is_file()}
declared = {(snapshot / row['path']).resolve() for row in record['files']}
assert actual == declared
for row in record['files']:
item = (snapshot / row['path']).resolve()
assert item.is_relative_to(snapshot)
verify(item, row)
checker = Path(record['command'][0])
verify(checker, {'sha256': record['checker_sha256']})
oracle_identities[str(checker.relative_to(root))] = digest(checker)
assert (trial / 'evidence' / (path.stem + '.log')).is_file()
checkpoint_files.update(actual)
checkpoint_records.append(path.relative_to(trial).as_posix())
assert checkpoint_files == {p.resolve() for p in (trial / 'checkpoints').rglob('*') if p.is_file()}
payloads = []
for name in ['preparation.json', 'launch.json', 'closure.json', 'stdout.log', 'stderr.log']:
payloads.append((trial / name, Path(name)))
for name in ['evidence', 'checkpoints', *baseline_names]:
for path in sorted((trial / name).rglob('*')):
if path.is_file():
assert path.resolve().is_relative_to(trial) and not path.is_symlink()
if name == 'evidence':
assert path.suffix.lower() in ['.png', '.json', '.log'], path
payloads.append((path, path.relative_to(trial)))
for name in ['canvas-native-paint-session.py', 'canvas-paint-checkpoint.py', 'canvas-native-checkpoint.py', Path(__file__).name]:
payloads.append((root / '.local' / name, Path('tools') / name))
payloads.append((stage / 'manifest.json', Path('stage/manifest.json')))
assert len({relative.as_posix() for _, relative in payloads}) == len(payloads)
assert not any(relative.parts[0] in ['profile', 'temp', 'compact-work', 'bound-work',
'draft-work', 'process-work'] for _, relative in payloads)
before = {str(path): digest(path) for path, _ in payloads}
destination.mkdir()
rows = []
for path, relative in payloads:
target = destination / relative
target.parent.mkdir(parents=True, exist_ok=True)
raw = path.read_bytes()
with target.open('xb') as stream:
stream.write(raw)
verify(target, before[str(path)])
rows.append({'path': relative.as_posix(), 'source_path': path.relative_to(root).as_posix(),
**before[str(path)]})
for path, _ in payloads:
verify(path, before[str(path)])
# Only append a scoped rule; never rewrite or normalize existing attributes.
attributes = root / '.gitattributes'
attribute_before = digest(attributes)
rule = prefix + '/** -text whitespace=-blank-at-eol,-blank-at-eof,cr-at-eol'
current = attributes.read_bytes()
added = rule.encode() not in current.splitlines()
if added:
assert (prefix + '/').encode() not in current, 'Review an existing prefix rule instead of replacing it'
with attributes.open('ab') as stream:
if current and not current.endswith(b'\n'):
stream.write(b'\n')
stream.write(rule.encode() + b'\n')
manifest = {'archived_utc': datetime.now(timezone.utc).isoformat(), 'source': source,
'native_trial': trial.relative_to(root).as_posix(), 'native_pid': launch['pid'],
'native_exit': closure['exit'], 'payload_count': len(rows),
'payload_bytes': sum(row['bytes'] for row in rows),
'verified_checkpoint_records': checkpoint_records, 'verified_baseline_files': len(baseline_records),
'oracle_binary_identities_not_native_app_source': oracle_identities,
'exclusions': ['profile', 'temp', 'compact-work', 'bound-work', 'draft-work', 'process-work'],
'byte_policy': 'Copied source bytes exactly, including CRLF; originals unmodified. Source paths are provenance, not portable execution paths.',
'attributes': {'rule': rule, 'appended': added, 'before': attribute_before, 'after': digest(attributes)},
'files': rows}
write_new(destination / 'manifest.json', manifest)
assert {p.relative_to(destination).as_posix() for p in destination.rglob('*') if p.is_file()} == {
row['path'] for row in rows} | {'manifest.json'}
result = {'archive': prefix, 'source': source, 'native_exit': closure['exit'],
'payload_count': len(rows), 'archive_file_count_including_manifest': len(rows) + 1,
'screenshots': sum(row['path'].endswith('.png') for row in rows),
'checkpoint_count': len(checkpoint_records), 'payload_bytes': manifest['payload_bytes'],
'all_payload_source_and_destination_hashes_equal': True,
'manifest': digest(destination / 'manifest.json'), 'helper': digest(Path(__file__)),
'attributes_rule_appended': added, 'git_staging_or_commit_performed': False}
write_new(result_path, result)
print(json.dumps(result, indent=2))