Files
digital-drosophila/models/male-cns-lif/conditioning-acceleration-v1/audit_integrity.py
T
2026-10-01 14:34:22 +08:00

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)