"""A new validation envelope; sealed brain implementations remain read-only.""" import hashlib import importlib.util import json import sys from pathlib import Path sys.dont_write_bytecode = True ROOT = Path('/data/digital-drosophila') MODEL = Path(__file__).resolve().parent EXP = ROOT / 'experiments/phase4ak-apl-timing-validation' AJ_MODEL = ROOT / 'models/male-cns-lif/apl-timing-lab-v1' AJ = ROOT / 'experiments/phase4aj-apl-timing' AG_MODEL = ROOT / 'models/male-cns-lif/author-apl-lab-v2' AG = ROOT / 'experiments/phase4ag-author-apl-r2' COEFF = ROOT / 'experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json' STATIC = ROOT / 'experiments/phase4l-olfactory-grounding' CFG = json.loads((MODEL / 'config.json').read_text(encoding='utf-8')) PINS = { 'models/male-cns-lif/apl-timing-lab-v1/manifest.json': '52b05dd1ff30b6b51ff960fe95904532f5c147731a83f0b5c31f98ca7e53c216', 'experiments/phase4aj-apl-timing/manifest.json': '7f490ada0db30785c61954d8b92147378ddc8bc16b229fe3808bbe501caff44a', 'models/male-cns-lif/phase4l.py': 'e97d58d8c1f44920d0e953f8f5831ddc86fa0198784e86460e315de4116ac553', 'models/male-cns-lif/olfactory-grounding-v1/phase4l.yaml': '9b8bcb7e031bf9063033a1854a439a7cd0bf6730301c2d2d02ca99a76f098d6e', 'models/male-cns-lif/apl-timing-lab-v1/gpu_timing.py': 'af1975ba5e5e700208c0a598d3cbe648a3cf10885c6231239b6e4b28f76d173b', 'models/male-cns-lif/apl-timing-lab-v1/oracle_timing.py': '39d8c47c94bc2faddf016864a43e7715907fb987f56f7b27098060a88851f6be', 'models/male-cns-lif/apl-timing-lab-v1/compare_timing.py': '9010f070fba9b7c9cf2d86187ee2abc57f3ac606ebc08a42baad4f3922b51734', 'models/male-cns-lif/apl-timing-lab-v1/timing_queue.py': '54df6d4818e2a0c26e96fb0aaf5d9b71cd964981706da937562d48af79aca14e', 'models/male-cns-lif/apl-timing-lab-v1/calibration.py': 'fb15ddeaa108305c8de697bbae36b23ab0414a7c58db51c66dce9feb4a048a0d', 'models/male-cns-lif/author-apl-lab-v2/calibration.py': 'edb9cb2d890471fd07afd88c959ef3540b0cd40af490fac3f26396b5e7f5bf9c', 'models/male-cns-lif/author-apl-lab-v2/validate_components.py': '5cfc9a4505da6b8fb4e7d2617cdaedaa8475ed46a11ec9bdf0d4d25b1d22c2d3', 'experiments/phase4l-olfactory-grounding/odor-encoder/frozen-odor-panel.parquet': '907f16a56e024a8e2112b5751e53b0e6037b329fa110098af3d31b119c10a1a0', 'experiments/phase4l-olfactory-grounding/odor-encoder/mapped-glomerular-vectors.npz': 'f057563152e0fa22060080af13019f319e7f36563a775eff829bbc1929c451b0', 'experiments/phase4l-olfactory-grounding/odor-encoder/selection.json': '1b832becf9d08935716fe9ba5e3cd3e619e7d208dfb43c4fa197c969d095f113', 'experiments/phase4l-olfactory-grounding/receptor-mapping/olfactory-mapping.parquet': 'a01d27000533e9844458a4c559cac084f1c34ca20a1104e97e6a0f72b0cc93b1' } def digest(path): result = hashlib.sha256() with Path(path).open('rb') as stream: for block in iter(lambda: stream.read(8 << 20), b''): result.update(block) return result.hexdigest() def load_module(name, path, expected_hash=None): path = Path(path) data = path.read_bytes() if expected_hash is not None: assert hashlib.sha256(data).hexdigest() == expected_hash, str(path) spec = importlib.util.spec_from_file_location(name, path) assert spec and spec.loader module = importlib.util.module_from_spec(spec) sys.modules[name] = module exec(compile(data, str(path), 'exec'), module.__dict__) return module def pinned(name, relative): return load_module(name, ROOT / relative, PINS[relative]) def read(path): return json.loads(Path(path).read_text(encoding='utf-8')) def save(path, value): path = Path(path) path.parent.mkdir(parents=True, exist_ok=True) with path.open('x', encoding='utf-8') as stream: json.dump(value, stream, indent=2, ensure_ascii=False, allow_nan=False) stream.write('\n') def sources(): return {p.relative_to(MODEL).as_posix(): digest(p) for p in sorted(MODEL.rglob('*')) if p.is_file() and '__pycache__' not in p.parts and p.name not in ('manifest.json', 'checksums.sha256')} def integrity(): old = load_module('sealed_aj_context_ak', AJ_MODEL / 'context.py') result = old.integrity() sys.path.insert(0, str(ROOT / 'models/male-cns-lif/terminal-scope-diagnostic-v1')) from diagnostic import manifest_check for path in (AJ_MODEL, AJ): result[str(path.relative_to(ROOT))] = manifest_check(path, digest) assert all(row['pass'] for row in result.values()) return result def check(): registered = read(EXP / 'protocol/preregistered.json') assert registered['sources'] == sources(), 'Registered validation source changed' assert registered['config'] == CFG for row in registered['inputs']: assert digest(ROOT / row['path']) == row['sha256'], row['path'] for row in read(EXP / 'protocol/prepared-hashes.json'): assert digest(EXP / row['path']) == row['sha256'], row['path'] return registered def budget(): size = sum(p.stat().st_size for p in EXP.rglob('*') if p.is_file()) assert size < CFG['output_budget_bytes'], 'Output budget exceeded; preserve partial evidence' return size def seal(root): rows = [dict(path=p.relative_to(root).as_posix(), bytes=p.stat().st_size, sha256=digest(p)) for p in sorted(root.rglob('*')) if p.is_file() and '__pycache__' not in p.parts] save(root / 'manifest.json', dict(root=str(root), files=rows)) with (root / 'checksums.sha256').open('x', encoding='utf-8') as stream: for row in rows: stream.write(row['sha256'] + ' ' + row['path'] + '\n') stream.write(digest(root / 'manifest.json') + ' manifest.json\n') def bit_equal(a, b): return a.dtype == b.dtype and a.shape == b.shape and a.tobytes() == b.tobytes()