50 lines
2.6 KiB
Python
50 lines
2.6 KiB
Python
"""Read-only rehash of the saved Phase4AR shutdown inventory and registered sources."""
|
|
import argparse
|
|
from datetime import datetime, timezone
|
|
import hashlib
|
|
import json
|
|
from pathlib import Path
|
|
import subprocess
|
|
import time
|
|
|
|
INVENTORY = Path('/home/qishizhe/phase4ar-user-shutdown-20260930T203113Z/saved-files.sha256.jsonl')
|
|
INVENTORY_SHA = 'd7b675b0d0d4647d8fe2fcf9616b9a599e5bc3c15565e604e0d66a046afb835a'
|
|
REG = Path('/data/digital-drosophila/experiments/phase4ar-normal-conditioning/protocol/preregistered.json')
|
|
REG_SHA = 'b63e6281b6505ca3b60acb467dd0b3fae274cf513dcbfd653649ba52e9ba9740'
|
|
|
|
def sha(path):
|
|
h = hashlib.sha256()
|
|
with Path(path).open('rb') as f:
|
|
for chunk in iter(lambda: f.read(8 << 20), b''): h.update(chunk)
|
|
return h.hexdigest()
|
|
|
|
p = argparse.ArgumentParser()
|
|
p.add_argument('--output', type=Path, required=True)
|
|
a = p.parse_args()
|
|
assert not a.output.exists() and a.output.parent.is_dir()
|
|
start = time.perf_counter()
|
|
assert sha(INVENTORY) == INVENTORY_SHA and sha(REG) == REG_SHA
|
|
records = [json.loads(line) for line in INVENTORY.read_text().splitlines()]
|
|
differences = []
|
|
for row in records:
|
|
path = Path(row['path'])
|
|
if not path.is_file() or path.stat().st_size != row['bytes'] or sha(path) != row['sha256']:
|
|
differences.append(str(path))
|
|
reg = json.loads(REG.read_text())
|
|
source_mismatches = [path for path, expected in reg['source_sha256'].items() if sha(path) != expected]
|
|
head = subprocess.check_output(['git', '-C', '/data/digital-drosophila', 'rev-parse', 'HEAD'], text=True).strip()
|
|
status = subprocess.check_output(['git', '-C', '/data/digital-drosophila', 'status', '--porcelain'], text=True)
|
|
summary = dict(status='PASS' if not differences and not source_mismatches and status == '' else 'FAIL',
|
|
created_utc=datetime.now(timezone.utc).isoformat(), files_checked=len(records),
|
|
bytes_checked=sum(r['bytes'] for r in records), inventory_sha256=INVENTORY_SHA,
|
|
registration_sha256=REG_SHA, registered_science_commit=reg['source_code_commit'],
|
|
sources_checked=len(reg['source_sha256']), file_mismatches=differences,
|
|
source_mismatches=source_mismatches, original_git_head=head, original_git_status=status,
|
|
wall_seconds=time.perf_counter()-start,
|
|
scope='Saved Phase4AR experiment/control files and registered source files; NOT a new Phase1-4AQ numerical regression',
|
|
training_epochs_cpu_verified_unchanged=1033, probes_completed_unchanged=138,
|
|
original_experiment_resumed=False)
|
|
with a.output.open('x') as f: json.dump(summary, f, indent=2)
|
|
print(json.dumps(summary), flush=True)
|
|
raise SystemExit(0 if summary['status'] == 'PASS' else 1)
|