"""Lock both validation cohorts before outcomes; read no old novel-odor dynamics.""" from datetime import datetime, timezone import ast import json import platform import shutil import subprocess import sys import numpy as np import pandas as pd import yaml from context import (ROOT, MODEL, EXP, AJ, AJ_MODEL, AG, CFG, PINS, STATIC, read, save, digest, sources, integrity, budget, bit_equal) from encoder_inputs import frozen_pn_drive, make_requests, write_npz def copy_exact(source, target): target.parent.mkdir(parents=True, exist_ok=True) with source.open('rb') as source_stream, target.open('xb') as target_stream: shutil.copyfileobj(source_stream, target_stream) assert digest(source) == digest(target) def main(): assert not EXP.exists() or not any(EXP.iterdir()), 'Never reuse a populated experiment' assert shutil.disk_usage(EXP.parent).free > CFG['output_budget_bytes'] + 10 * 1024**3 for relative, expected in PINS.items(): assert digest(ROOT / relative) == expected, relative previous = read(AJ / 'audit/final-status.json') assert previous['status'] == 'PASS-FIXED-CAL-APL-TIMING-HYPOTHESIS' assert previous['delay18_representation_pass'] and previous['old_frozen_integrity_and_five_reference_pass'] assert CFG['apl'] == read(AJ_MODEL / 'config.json')['apl'] assert CFG['gates'] == read(AJ_MODEL / 'config.json')['gates'] assert CFG['apl_delay_steps'] == 18 and not CFG['training'] and not CFG['candidate_generation'] seed_audit = read(MODEL / 'seed-audit.json') assert seed_audit['proposed_seeds'] == CFG['validation']['seeds'] and seed_audit['collision_found'] is False seed_sources = [] for row in seed_audit['inspected_files']: if row.get('remote_path'): path = ROOT / row['remote_path'] assert path.is_relative_to(ROOT) and '..' not in path.parts assert digest(path) == row['sha256'], row['remote_path'] seed_sources.append(dict(path=path.relative_to(ROOT).as_posix(), sha256=row['sha256'])) assert seed_sources, 'At least exact-mapped static seed sources must be checked on server' for name in ('protocol', 'cases', 'gpu', 'oracle', 'component-audit', 'audit', 'validation', 'regression', 'logs', 'extension-build'): (EXP / name).mkdir(parents=True, exist_ok=False) command = [sys.executable, '-B', '-m', 'unittest', 'discover', '-v', '-s', str(MODEL), '-p', 'test_*.py'] test = subprocess.run(command, cwd=MODEL, text=True, capture_output=True) with (EXP / 'regression/unit-tests.log').open('x', encoding='utf-8') as stream: stream.write(test.stdout + test.stderr) save(EXP / 'regression/unit-tests.json', dict(command=command, exit_code=test.returncode, pass_all=test.returncode == 0, sha256=digest(EXP / 'regression/unit-tests.log'))) assert test.returncode == 0 inputs = {relative: expected for relative, expected in PINS.items()} for row in seed_sources: inputs[row['path']] = row['sha256'] for path in (AJ / 'audit/final-status.json', AJ / 'protocol/preregistered.json', AG / 'protocol/calibration-cases.json', AG / 'protocol/encoder-audit.json'): inputs[path.relative_to(ROOT).as_posix()] = digest(path) save(EXP / 'protocol/preregistered.json', dict(timestamp_utc=datetime.now(timezone.utc).isoformat(), sources=sources(), config=CFG, inputs=[dict(path=path, sha256=sha) for path, sha in sorted(inputs.items())], parent_commit=subprocess.check_output(['git', '-C', str(ROOT), 'rev-parse', 'HEAD'], text=True).strip(), prior_AJ_CAL_outcomes_known=True, before_new_requests_and_brain_trajectories=True, training=False, candidate_generated=False, historical_never_simulated_odor_claim=False, seed_collision_audit_scope='Only enumerated static sources and explicitly evaluated derivations; no universal independence claim', shared_seed_across_conditions=True, new_dynamic_scope='seed_validation then conditionally novel_to_aj', source_engine='Unmodified SHA-pinned AJ backend functions, using original __file__ and globals', oracle_limit='Independent Brian LIF and delay FIFO, shared frozen Torch APL component', python=sys.version, machine=platform.machine(), numpy=np.__version__)) save(EXP / 'regression/old-integrity-before.json', integrity()) from run_case import preflight preflight() import torch cfg_path = ROOT / 'models/male-cns-lif/olfactory-grounding-v1/phase4l.yaml' oc = yaml.safe_load(cfg_path.read_text()) assert oc['odor_encoder']['duration_ms'] == CFG['validation']['duration_ms'] assert oc['odor_encoder']['modes'] == CFG['validation']['modes'] panel = pd.read_parquet(STATIC / 'odor-encoder/frozen-odor-panel.parquet') assert len(panel) == 12 and panel.odor_id.is_unique assert panel.split.tolist() == ['calibration'] * 6 + ['heldout'] * 6 median = float(np.median(panel.mapped_response_sum)) assert median == CFG['validation']['median_mapped_response_sum'] selection = read(STATIC / 'odor-encoder/selection.json') mapping = pd.read_parquet(STATIC / 'receptor-mapping/olfactory-mapping.parquet') with np.load(STATIC / 'odor-encoder/mapped-glomerular-vectors.npz', allow_pickle=False) as source: assert set(source.files) == set(panel.odor_id) | {'glomeruli'} assert source['glomeruli'].tolist() == selection['glomeruli_order'] vectors = {oid: source[oid].copy() for oid in panel.odor_id} encoder_source = ROOT / 'models/male-cns-lif/phase4l.py' drive, ast_sha = frozen_pn_drive(encoder_source, PINS[str(encoder_source.relative_to(ROOT))]) cached = {} static_rows = {} for cohort, frame in (('seed_validation', panel.iloc[:6]), ('novel_to_aj', panel.iloc[6:])): static_rows[cohort] = [dict(odor_id=str(odor.odor_id), odor_index=index, source_panel_split=str(odor.split)) for index, (_, odor) in enumerate(frame.iterrows())] for mode in CFG['validation']['modes']: for index, (_, odor) in enumerate(frame.iterrows()): targets, rates, ignored_frame = drive(str(odor.odor_id), vectors[odor.odor_id], mapping, selection['glomeruli_order'], mode, median, oc) assert targets.dtype == np.int32 and rates.dtype == np.float32 and len(targets) > 0 assert len(np.unique(targets)) == len(targets) and np.all((targets >= 0) & (targets < CFG['neurons'])) assert np.isfinite(rates).all() and np.all(rates > 0) cached[(cohort, mode, index)] = (targets, rates) # Reproduce all 60 known CAL input arrays, without any old heldout trajectory. control_rows = [] old_inventory = read(AG / 'protocol/calibration-cases.json') assert len(old_inventory) == 60 for row in old_inventory: targets, rates = cached[('seed_validation', row['mode'], row['odor_index'])] old_case = AG / 'cases' / row['name'] spec = read(old_case / 'spec.json') assert spec['odor_id'] == static_rows['seed_validation'][row['odor_index']]['odor_id'] with np.load(old_case / 'pn-drive.npz', allow_pickle=False) as old: assert bit_equal(targets, old['targets']) and bit_equal(rates, old['rates_hz']) requests = make_requests(targets, rates, row['seed']) with np.load(old_case / 'requests.npz', allow_pickle=False) as old: assert bit_equal(requests[:, 0], old['tick']) and bit_equal(requests[:, 1], old['neuron_idx']) control_rows.append(dict(case=row['name'], pass_all=True, seed=row['seed'], old_requests_sha256=digest(old_case / 'requests.npz'), old_drive_sha256=digest(old_case / 'pn-drive.npz'), target_rate_and_request_arrays_bitwise=True)) save(EXP / 'protocol/encoder-control.json', dict(pass_all=True, cases=control_rows, old_heldout_dynamic_access=False, comparison='All original 60 CAL request/drive arrays; no trajectory or RNG-column reorder')) template = read(AJ / 'cases/delay18' / CFG['control_cases'][0] / 'spec.json') assert template['apl_delay_steps'] == 18 and template['steps'] == 1000 and template['record_history'] is False control_cases = [] for name in CFG['control_cases']: source = AJ / 'cases/delay18' / name target = EXP / 'cases/controls' / name target.mkdir(parents=True, exist_ok=False) spec = read(source / 'spec.json') spec.update(budget_root=str(EXP), output_budget_bytes=CFG['output_budget_bytes']) save(target / 'spec.json', spec) for filename in ('requests.npz', 'pn-drive.npz'): copy_exact(source / filename, target / filename) control_cases.append(dict(name=name, source_case=str(source), source_output=str(AJ / 'gpu/delay18' / (name + '-r0')))) save(EXP / 'protocol/control-cases.json', control_cases) records = [] for cohort, frame in (('seed_validation', panel.iloc[:6]), ('novel_to_aj', panel.iloc[6:])): for mode in CFG['validation']['modes']: for index, (_, odor) in enumerate(frame.iterrows()): targets, rates = cached[(cohort, mode, index)] for seed in CFG['validation']['seeds']: requests = make_requests(targets, rates, seed) name = f'{cohort}-{mode}-{index:02d}-s{seed}' target = EXP / 'cases' / cohort / name target.mkdir(parents=True, exist_ok=False) expected = float(rates.sum()) * 1000 * .1 / 1000. spec = dict(template, name=name, kind='fullgraph', validation_cohort=cohort, source_panel_split=str(odor.split), source_panel_row=int(odor.name), odor_id=str(odor.odor_id), odor_name=str(odor.odor_name), mode=mode, seed=seed, odor_index=index, expected_external_events=expected, target_count=len(targets), rate_sum_hz=float(rates.sum()), budget_root=str(EXP), output_budget_bytes=CFG['output_budget_bytes']) save(target / 'spec.json', spec) write_npz(target / 'requests.npz', tick=requests[:, 0], neuron_idx=requests[:, 1]) write_npz(target / 'pn-drive.npz', targets=targets, rates_hz=rates) records.append(dict(name=name, cohort=cohort, source_panel_split=str(odor.split), source_panel_row=int(odor.name), mode=mode, odor_id=str(odor.odor_id), odor_index=index, seed=seed, targets=len(targets), requests=len(requests), expected_external_events=expected, rates_sum=float(rates.sum()))) assert len(records) == 120 and len({row['name'] for row in records}) == 120 save(EXP / 'protocol/validation-cases.json', records) save(EXP / 'protocol/encoder-audit.json', dict(panel_count=12, cal_count=6, novel_to_aj_count=6, median_mapped_response_sum=median, seeds=CFG['validation']['seeds'], seeds_static_audit_sha256=digest(MODEL / 'seed-audit.json'), cohorts_static_panel_rows=static_rows, requested_before_any_dynamics=True, historical_never_simulated_claim=False, old_heldout_dynamic_access=False, seed_namespace_universally_independent_claim=False, source_function='Unmodified AST node pn_drive from pinned phase4l.py; only np/pd/typing dependencies', source_sha256=digest(encoder_source), function_ast_sha256=ast_sha, torch=torch.__version__, numpy=np.__version__, control_60_original_CAL_arrays_exact=True, target_rng_column_order='Original function output, unchanged', generation='Original float32 rates*.1/1000 GPU Bernoulli; same seed across conditions; sort only resulting sparse requests', expected_not_realized_input_energy_matched=True, no_learning=True)) save(EXP / 'protocol/prepared-hashes.json', [dict(path=p.relative_to(EXP).as_posix(), sha256=digest(p), bytes=p.stat().st_size) for directory in ('protocol', 'cases') for p in sorted((EXP / directory).rglob('*')) if p.is_file() and p.name != 'prepared-hashes.json']) budget() print('REGISTERED 2 controls +120 fixed validation cases; 60 original input arrays exact; no brain trajectories', flush=True) if __name__ == '__main__': main()