Files
2026-09-30 13:58:39 +08:00

117 lines
5.3 KiB
Python

"""New read-only audit envelope. All old payloads are hash-anchored inputs."""
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/phase4al-mb-credit-transfer'
AK = ROOT / 'experiments/phase4ak-apl-timing-validation'
AK_MODEL = ROOT / 'models/male-cns-lif/apl-timing-validation-v1'
H = ROOT / 'experiments/phase4h-dopamine-plasticity'
AG = ROOT / 'experiments/phase4ag-author-apl-r2'
CORE = ROOT / 'models/male-cns-lif/kc-drive-audit-v1/replay_core.py'
META = ROOT / 'datasets/male-cns-v1.0/processed/neuron-only/neuron-index/unified-metadata.parquet'
COEFF = ROOT / 'experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json'
CFG = json.loads((MODEL / 'config.json').read_text(encoding='utf-8'))
PINS = {
'models/male-cns-lif/runtime-credit-v1/phase4o_event_replay.py': 'b169937bab495c77d8ee6c1013877e7500e7354140d9fcc90595d984238ba44e',
'models/male-cns-lif/phase4l.py': 'e97d58d8c1f44920d0e953f8f5831ddc86fa0198784e86460e315de4116ac553',
'models/male-cns-lif/apl-timing-validation-v1/manifest.json': '3206a8666718b4a99e09b8384c87dd25895b5d7038d23fad7b93e40379183ccb',
'experiments/phase4ak-apl-timing-validation/manifest.json': '25eb7e467eb17c3fa83ffee2e4e82b754f161fd8891e515bed23eeb500c5656d',
'models/male-cns-lif/apl-timing-validation-v1/context.py': '5e4e500d5ec777bb8ae7ff77ac9a7279bfe995b1a17be2baededdbe065c98b73',
'experiments/phase4ak-apl-timing-validation/protocol/validation-cases.json': '50d7b3aa7b0235e8f7bc1e21ef693cd5c554272ef3bd205c72f61e8e07ad1fd9',
'experiments/phase4ak-apl-timing-validation/audit/final-status.json': 'c49181086ecbd19511b9f1e783afea8f66d0f74348a7b70d7f6c5fa99b4337fc',
'models/male-cns-lif/kc-drive-audit-v1/replay_core.py': 'aa3187cb23712c09ab603e27e60424294db92de8086d60a95cf7a629d0521fdc',
'models/male-cns-lif/mb-physiology-v1/phase4j.py': 'abb4574da85f00bd9ef61024c65993ef81d42651ff8d8d63c15dd69c6222471e',
'models/male-cns-lif/mb-physiology-v1/phase4j.yaml': 'b35e4332a91b8489f69348cedf5ac675e9c3902c7e8c7beec5d053773c6529a3',
'experiments/phase4h-dopamine-plasticity/manifests/checksums.sha256': '1ea0394fd0477bb40d656ed0854108964f3809d633b5561bed9de43cda630ba1',
'datasets/male-cns-v1.0/processed/neuron-only/neuron-index/unified-metadata.parquet': '922af16846a065c3dbfca7c11146b83ca217fcbd7392edc745f444a04eae8c63'
}
def digest(path):
h = hashlib.sha256()
with Path(path).open('rb') as f:
for block in iter(lambda: f.read(8 << 20), b''):
h.update(block)
return h.hexdigest()
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 f:
json.dump(value, f, indent=2, ensure_ascii=False, allow_nan=False)
f.write('\n')
def write_npz(path, **values):
import numpy as np
with Path(path).open('xb') as f:
np.savez_compressed(f, **values)
def load_module(name, path, expected_hash):
data = Path(path).read_bytes()
assert hashlib.sha256(data).hexdigest() == expected_hash, str(path)
spec = importlib.util.spec_from_file_location(name, path)
module = importlib.util.module_from_spec(spec)
sys.modules[name] = module
exec(compile(data, str(path), 'exec'), module.__dict__)
return module
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():
previous = load_module('sealed_ak_context_al', AK_MODEL / 'context.py',
PINS['models/male-cns-lif/apl-timing-validation-v1/context.py'])
result = previous.integrity()
sys.path.insert(0, str(ROOT / 'models/male-cns-lif/terminal-scope-diagnostic-v1'))
from diagnostic import manifest_check
for path in (AK_MODEL, AK):
result[path.relative_to(ROOT).as_posix()] = manifest_check(path, digest)
assert all(row['pass'] for row in result.values())
return result
def check():
reg = read(EXP / 'protocol/preregistered.json')
assert reg['sources'] == sources() and reg['config'] == CFG
for row in reg['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 reg
def bit_equal(a, b):
return a.dtype == b.dtype and a.shape == b.shape and a.tobytes() == b.tobytes()
def budget():
size = sum(p.stat().st_size for p in EXP.rglob('*') if p.is_file())
assert size < CFG['output_budget_bytes'], 'Audit output budget exceeded; stop, preserve partials'
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 f:
for row in rows:
f.write(row['sha256'] + ' ' + row['path'] + '\n')
f.write(digest(root / 'manifest.json') + ' manifest.json\n')