import hashlib import importlib.util import json from pathlib import Path MODEL = Path(__file__).resolve().parent ROOT = Path('/data/digital-drosophila') EXP = ROOT/'experiments/phase4af-author-fullgraph' AD = ROOT/'experiments/phase4ad-author-semantics' AE_MODEL = ROOT/'models/male-cns-lif/author-runtime-lab-v1' AE_EXP = ROOT/'experiments/phase4ae-author-runtime' CFG = json.loads((MODEL/'config.json').read_text(encoding='utf-8')) def digest(path): h = hashlib.sha256() with Path(path).open('rb') as f: for b in iter(lambda: f.read(8<<20), b''): h.update(b) return h.hexdigest() def save(path, value): path = Path(path); path.parent.mkdir(parents=True, exist_ok=True) with path.open('x', encoding='utf-8') as f: json.dump(value, f, indent=2, ensure_ascii=False, allow_nan=False); f.write('\n') def sources(): return {p.name: digest(p) for p in sorted(MODEL.iterdir()) if p.is_file() and p.name not in ('manifest.json', 'checksums.sha256')} def check(): p = json.loads((EXP/'protocol/preregistered.json').read_text()) assert sources() == p['sources'], 'Source changed after preregistration' for row in p['inputs']: assert digest(ROOT/row['path']) == row['sha256'], row['path'] for row in json.loads((EXP/'protocol/graph-case-hashes.json').read_text()): assert digest(EXP/row['path']) == row['sha256'], row['path'] return p def integrity(): spec = importlib.util.spec_from_file_location('previous_ae_context', AE_MODEL/'context.py') previous = importlib.util.module_from_spec(spec); spec.loader.exec_module(previous) result = previous.integrity() import sys sys.path.insert(0, str(ROOT/'models/male-cns-lif/terminal-scope-diagnostic-v1')) from diagnostic import manifest_check for p in (AE_MODEL, AE_EXP): result[str(p.relative_to(ROOT))] = manifest_check(p, digest) assert all(r['pass'] for r in result.values()) return result def output_bytes(): return sum(p.stat().st_size for p in EXP.rglob('*') if p.is_file()) def budget_check(): assert output_bytes() < CFG['new_output_budget_bytes'], 'New output budget exceeded'