Seal Phase 4AK frozen D18 independent validation

This commit is contained in:
Digital Drosophila Archive
2026-09-30 13:18:18 +08:00
parent cb6937666f
commit c6444255fe
1313 changed files with 154250 additions and 15 deletions
@@ -0,0 +1,81 @@
# Phase 4AK — frozen D18 validation, not learning
Prerequisite: the entire Phase 4AJ fixed-CAL experiment was completed, sealed
and published at cb6937666f96b00ae8d435a2cfb2f417ad25c040.
Its PASS is not evidence of usable learning. This stage tests the next necessary
representation-generalization gate without adjusting the successful branch.
## No new brain dynamics
Call the exact SHA-pinned AJ GPU, Brian oracle, comparison and timing code from
their original absolute paths. Do not copy or patch their numerical functions,
globals, signs, weights, thresholds, APL gain/tau, refractory or delay queue.
Keep dt=0.1 ms, anatomical delay=18 steps, and whole generated graded-APL h
applied 18 steps later. Preserve positive-zero initialization and pending tail;
never advance brain time to drain the tail. Shared APL arithmetic limits the
oracle independence claim. The 5845 fast-APL output mask, including 1212
unreplaced non-KC edges, is unchanged. No biological measurement claim.
## Input registration and data boundary
Read only the four SHA-pinned original static 4L encoder files (panel, vectors,
selection, mapping) and pinned encoder configuration/source. Extract only the
unchanged pn_drive function AST; do not import or execute unrelated learning
experiments. Validate the extraction and request generator against all 60 old
AG CAL request/PN-drive arrays before generating any new brain trajectory.
Keep the original 12-odor median 2.556107997894287 and original target/RNG column
order. Matched energy is expected input, not exactly equal realized events.
Predeclare both 6-odor x2-mode x5-seed blocks, every sparse request schedule,
source hash, gate, and stop rule before any new brain trajectory. Seeds are the
fixed first five integers above 2^30, subject to the enumerated static collision
audit. They are not chosen using simulation outcomes. Do not claim exhaustive
historical uniqueness, statistical independence of RNG streams, or biological
replication. Same seed across odors preserves the existing paired comparisons.
The second six odors are novel to AG/AJ calibration, not never simulated in
project history: old 4L traversed the full panel. Never open old heldout dynamic
results, mixed old result tables or conditioning/plasticity reports to choose
inputs. Full frozen-integrity hashing may read opaque bytes for checksums; that
is not permission to parse those outcomes. Static A/B identities are not used
to select a favorable subset. No new resource download.
## Ordered execution
1. Freshly run the two original AJ D18 fullgraph probe inputs. Verify every
scientific output against sealed AJ, allowing only output budget/path
differences in spec. Do not fake D0 to use a D0-only helper. Old eight-fixture
proofs are source-pinned inherited evidence, not newly rerun fixture claims.
2. For original CAL odors on new seeds, fixed first odor/first seed in each mode
is a Brian fullgraph probe, with independent LIF/own spikes/FIFO and the
existing shared-APL component audit. Any numerical failure stops.
3. Complete the 60 seed-validation trajectories plus 12 exact repeats. Reuse
the two probe GPU runs rather than duplicate them as independent samples.
4. Only if the entire seed block passes numerical, repeat and original
representation gates, unlock the second block. Run the first static novel
odor/first seed in each mode as two additional Brian probes, then complete
that block's 60 trajectories and 12 repeats. All planned conditions remain
visible; gated unexecuted cases are NOT PASS and are reported as such.
5. Recompute raw evidence, rerun the five old frozen reference trials into new
output, verify every frozen artifact, and seal a truthful result.
Each cohort/mode separately retains every original six-part 4L gate: mean KC
fraction in [3%,9%], all runs >0 and <50%, same-odor Jaccard > different-odor,
between-odor Euclidean > within-odor, and at least 3 of 15 odor pairs passing
their own two-odor within baseline. Every mode has 60 within comparisons and
75 between comparisons; each pair has 20 within and 5 between. No pooled
12-odor rescue, seed replacement, post-hoc metric/window/gate changes or scans.
## Outcome scope
PASS-FROZEN-D18-INDEPENDENT-VALIDATION requires all four cohort/mode gates,
complete data, fresh controls, oracle/component checks, exact repeats and old
frozen integrity/reference PASS. Scientific failure remains FAIL; incomplete
execution is not re-labelled scientific success. Passing does not generate a
candidate, establish learning, prove delay biology or repair upstream AL loops.
Next required gates remain credit specificity, real KC-to-MBON functional
transfer, whole-brain stimulus-specific response, and controlled conditioning.
All outputs are new under phase4ak-apl-timing-validation. Previous Phase 1–4AJ,
base CSR/W_syn/signs, eligibility-v2 and the 14232-edge plastic mask remain
read-only. No training, reward interface, game, vision, decoder, RL or Web.
@@ -0,0 +1,64 @@
# Phase 4AK:仅静态种子审计
状态:`NO-COLLISION-FOUND-IN-DECLARED-STATIC-SCOPE`。这是输入准备审计,不是科学运行、表征验证或学习 PASS。
## 固定选择
使用 `2^30` 后的首五个正整数:
```text
1073741825, 1073741826, 1073741827, 1073741828, 1073741829
```
它们均小于 `2^31`。选择只依据静态声明的历史 namespace 与固定算术规则;没有生成随机输入来挑选、没有检查活动或 separability,也没有读取旧 held-out 动态结果。
新运行直接把这些整数传给原始 CUDA generator,不增加 odor、mode 或验证块偏移。两验证块、气味及模式继续按已提交计划共享同一组 seeds,以保留配对设计;技术重复重用同一 seed。这不意味着跨气味、模式或验证块的随机流彼此独立,也不是生物重复。运行后不得因结果不利换 seeds。
## 本次覆盖范围
先阅读已提交的 `phase4aj-next-validation.md`,随后只审计本地静态源码、配置及 AG/AJ 输入清单。机器记录见同目录 `seed-audit.json`:
- 217 个静态文件,每个记录 workspace-relative 路径、字节数和 SHA-256。
- 1,432 条 seed/RNG 相关源码或配置行保留准确行号;词法证据包括测试与非 RNG 的 `seed_node`,不把每一数字都当成真正 RNG seed。
- 检索范围为文件中列出的 12 个 source 根目录内 `.py/.yaml/.yml/.json`,排除名字含 manifest/checksum 的文件;另纳入已提交计划与明确允许的 AG/AJ protocol 静态文件。
- 完整文件文本未发现五个新种子的十进制字面值;已检查的配置及派生规则也未发现重用。
- AG 和 AJ 的 `protocol/calibration-cases.json` 均为 60 项,seeds 为 `51101–51105`,odor indices 为 `0–5`,两份文件 SHA 完全相同:`d91994c77db82cb40a258c92b222e0d7b28338ffe98764bd600988dae6f72754`。
没有导入或执行旧源码,没有运行 GPU/脑实验,没有访问网络或远程服务器,没有打开旧 `kc-representation`、`eligible-edges`、`plasticity-magnitude`、`conditioning` 或包含它们结果的综合报告。源码中的旧路径字符串是静态文本,不代表这些路径的输出被读取。
## 不能漏掉的派生规则
| 静态来源 | 已声明规则/占用范围 |
|---|---|
| 4A–4D | 配置中的 `41xxx–44xxx`;4C visual seed 加 `1/2/3/4/10+j`;4D 还内联 `44301–44303`。 |
| 4E | `45000 + SHA256(layer)前4字节模1000000`,再加 amplitude/rate/sparsity/window 派生偏移;保守保留完整 hash 输出范围,不读取旧最优条件。 |
| 4F/4G | `46101–46103`、`47001–47005`、`47101–47103`、`47201–47205`、`47300`、`47400`、`47901/47902`。4G 的 `stable_seed` 定义被记录,但其源码没有调用,不能宣称已执行。 |
| 4H–4K | 训练 seed 加 trial index;4J calibration base 加 odor index、evaluation seed 加 `odor_index*100`;4I 固定随机集合 seed `49301`;若干 DAN helper 接收 `seed+991`,显式 pulse 路径不实际抽样,仍保守记录。 |
| 4L–4Q | `51201–51205 + pairing(1..100)`,包括 `ts+pairing` 别名;评估 `51301–51305`;4N random-US 再加 `700000`。`512xx/513xx` 不可当作空白 namespace。 |
| 4P/4Q/4R | 旧 odor seed 有 `seed+odor_index*100`;`52101–52105` 和 `52201–52205` 已明确声明。random-US 包括 `930000/950000+actual`;4Q formal 还使用 `940000+train_seed*1000+pairing`。 |
| 4S | `54101–54105` 或 `55101–55105 + odor_index*100000`;control 加 `975000`;formal `[61000,62000,63000,64000,65000]+pairing`,评估 `71001–71005`。 |
| 4T | `86101–86120` 或 `87101–87120 + odor_index*1000000`;live-US RNG 加 `9700000`。 |
| 4U | `50000000 + odor_index*2000000 + seed`,seed 为 `118101–118120` 或 `119101–119120`;control 另加 `29000000`。按已声明最多 12 气味取保守 index `0..11`,最大列出参数为 `101119120`。 |
| 4V/W/Y/Z、4AB terminal scope | `80000000 + odor_index*1000000 + seed + block*1000003`;seed 包括 `131101–131103/141101`。1000 ms 以 120 ms 分块,保守含 `block=0..8`;offset 模式也先生成这些块再清零,不能忽略 RNG 使用。 |
| 4AE | 数值夹具固定 seed `410301`。 |
| AG/AJ、AH/AI | AG/AJ 每 case 直接使用 `51101–51105`,没有旧 4P 的 odor 偏移;AH/AI 使用既有轨迹重建,并非新 RNG 流。AF/motif 的 `seed_node(s)` 是 neuron IDs,不是 RNG seeds。 |
这些固定配置和已解释公式保守保留在 `[0, 200000000]` 排除区间;这不是说区间内所有整数都实际用过。新种子在该区间之外。完整规则、源码路径和原始行见 JSON。
## SHA 与远端核验契约
本地 `phase4l.yaml` 的 SHA 与 AG-r2 已登记 `olfactory-grounding-v1/phase4l.yaml` 相同;本地 `phase4p_revalidate.py` 与已登记 `deterministic-runtime-v2/phase4p_revalidate.py` 相同。
JSON 的 `inspected_files` 提供 `local_path/sha256/remote_path`。仅对有确切模型相对路径且 SHA 匹配预注册的 AG/AJ sources、两个上述输入 pin,以及明确的 experiment/protocol 副本填写 remote_path,共 43 项。remote_path 均相对于 `/data/digital-drosophila`。其他本地平铺副本一律为 null,不能猜服务器子目录。
主流程应在注册前对非 null 远端路径再次校验 SHA,并执行自身的旧文件及 manifest-chain 完整性检查;本静态审计不替代服务器完整性验证。
## 严格限制
1. 未审计未列出的 server-only 文件、终端历史、CLI 覆写、其他分支/历史版本、外部包或其他用户的运行;因此不能说全历史绝对未用过。
2. 配置中允许某 seed 不等于历史实际执行过;反之,任意 `reset(seed)` 或外部 caller 可以传入未在配置里列出的整数。词法检索与命名调用点复核不是完整 Python 数据流证明。
3. 没有完整历史执行输入注册表;只审计 AG/AJ 两份明确静态 CAL 清单,没有读取旧动态输出来反推使用情况。
4. 新整数不构成 PRNG 流统计独立性的数学证明。后六气味仅称“未用于 AG/AJ 校准”,不是项目历史从未运行过。
5. 主代理同时创建的 Phase 4AK 文件不属于历史检索范围,避免候选自身造成字面碰撞;本记录必须在新轨迹前纳入预注册。
结论仅为:这五个值在所列静态证据及配置派生范围内未发现重用,符合本轮预声明选择规则。未开始验证块、conditioning、参数扫描或候选升级。
@@ -0,0 +1,18 @@
2d3996933b6e5a31e6a737ade5f3ae6869ffd03e01002c793eccf9b4f71e987d PROTOCOL.md
35e8bfe1bff62f3a5d9295c785e1b8cec8a2393eaa67d6c683046e48f30feb56 SEED-AUDIT.md
1718d8b01ece24930ff138f25c88f2f0e0f1cf69ad0ba655e5a0de5083e64df2 config.json
5e4e500d5ec777bb8ae7ff77ac9a7279bfe995b1a17be2baededdbe065c98b73 context.py
0061689abb1832e963718bd836bc8a50009ee38b258143a753b4d59e63414925 encoder_inputs.py
7eb638c357cec7f5f85032312c50a616402b5a8a9ab5aa0268c181f6c3ae0ce5 finalize.py
d8b8315f8800b3efdc7548620f0fae85da21a12b753b9985dd623bd529e2c50f prepare.py
bba6c4a98c6edf1eaba60b8030a9eca646da7dd30b74b2a0c16e374efd022bfa run_case.py
3d9890f11f299c07956faa5c0a9ebe2ea28ade58d8acf01a8631c17025073345 run_suite.py
8a6629f8cd991cf309b508c670b3009737f9b5f5e1f72560fa5bd4b1ff0bc64d runtime_bridge.py
e14c0deb94432787aa1cac7618254aeb3db0bcd5b1d8328e20428496d38b220a seed-audit.json
f1b3b8a0ca9bc41152485c05fd5f24fb7bb1f76c6ea111ffb941ae1225d914fe test_encoder_inputs.py
a85466891352c15b3103d30e7229734ad6694c8a1347d5e0747da3315223c203 test_final_status.py
bc01a5ff38d79a7b66ab2eb9e6731164bb8a1e15b5b5c0c1655161c24e2c37cf test_runtime_bridge.py
03f5aacb5a1f9460d10b30744100a43c57e5488d32dada79c888529943c82cf0 test_validation.py
3464091a4cc2cba18946cb9c9b3d12a69bd3f79f1001096234b3a8467dc602c5 validation.py
a736b774e39ff0ad863e8efc720bd5f9ed7d30261776bb57f0a716a7052dba5a verify_frozen.py
3206a8666718b4a99e09b8384c87dd25895b5d7038d23fad7b93e40379183ccb manifest.json
@@ -0,0 +1,35 @@
{
"phase": "4AK",
"name": "apl-timing-validation-v1",
"human_authorization": "允许独立新模型分支测试动力学假设",
"gpu_uuid": "GPU-79f3a85d-adce-7833-7003-6488140ca596",
"neurons": 166700,
"edges": 25582938,
"raw_weight_sum": 124177617,
"apl_delay_steps": 18,
"dt_ms": 0.1,
"apl": {"tau_ms": 20.0, "gain": 0.01, "normalization": 1.0},
"validation": {
"seeds": [1073741825,1073741826,1073741827,1073741828,1073741829],
"modes": ["physiological", "matched_energy"],
"duration_ms": 100.0,
"odor_count": 6,
"repeat_first_seed_each_odor": true,
"cohorts": ["seed_validation", "novel_to_aj"],
"median_scope": "unchanged original frozen 12-odor panel",
"median_mapped_response_sum": 2.556107997894287,
"full_oracle_policy": "first static odor, first seed, each mode, for each cohort",
"unlock_novel": "Complete seed_validation execution, representation and repeat gates must pass before any novel-to-AJ brain trajectory"
},
"gates": {"sparse_min_fraction": 0.03, "sparse_max_fraction": 0.09, "max_fraction_strict": 0.5, "min_fraction_strict": 0.0, "minimum_separable_odor_pairs": 3, "same_jaccard_gt_between": true, "between_euclidean_gt_within": true, "both_modes_required": true, "finite_required": true, "repeat_exact_required": true},
"control_cases": ["cal-physiological-00-s51101", "cal-matched_energy-00-s51101"],
"output_budget_bytes": 25769803776,
"training": false,
"candidate_generation": false,
"old_heldout_dynamic_access": false,
"new_validation_dynamic_execution": true,
"historical_never_simulated_odor_claim": false,
"universal_seed_independence_claim": false,
"selection_policy": "Fixed source panel order, both cohorts and input schedules registered before any new trajectory. Stop on numerical failure or seed-block representation failure; retain all results, no replacement seeds/odors, no tuning, no pooled gate rescue.",
"hypothesis": "The already frozen AJ D18 operator generalizes to new audited seeds and six odors not used in AG/AJ calibration. No change whatsoever to dynamics, input transform, temporal window, graph, signs, APL mask or metric definitions."
}
@@ -0,0 +1,120 @@
"""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()
@@ -0,0 +1,52 @@
"""Static-only frozen encoder extraction and exact request-schedule generation."""
import ast
import hashlib
from pathlib import Path
from typing import Any
import numpy as np
def frozen_pn_drive(path, expected_sha):
"""Execute the exact one pure function, not unrelated historical experiments."""
import pandas as pd
source = Path(path).read_bytes()
assert hashlib.sha256(source).hexdigest() == expected_sha
tree = ast.parse(source, filename=str(path))
nodes = [node for node in tree.body if isinstance(node, ast.FunctionDef) and node.name == 'pn_drive']
assert len(nodes) == 1 and not nodes[0].decorator_list
module = ast.Module(body=nodes, type_ignores=[])
namespace = {'np': np, 'pd': pd, 'Any': Any}
exec(compile(module, str(path), 'exec'), namespace)
return namespace['pn_drive'], hashlib.sha256(ast.dump(nodes[0], include_attributes=False).encode()).hexdigest()
def requests_from_forced(forced, targets):
targets = np.asarray(targets)
assert targets.dtype == np.int32 and targets.ndim == 1 and len(np.unique(targets)) == len(targets)
assert forced.dtype == np.bool_ and forced.ndim == 2 and forced.shape[1] == len(targets)
ticks, columns = np.nonzero(forced)
requests = np.column_stack([ticks, targets[columns]]).astype(np.int32)
if len(requests):
requests = requests[np.lexsort((requests[:, 1], requests[:, 0]))]
assert np.all(np.diff(requests[:, 0].astype(np.int64) * 166700 + requests[:, 1]) > 0)
return requests
def make_requests(targets, rates, seed, steps=1000):
import torch
assert rates.dtype == np.float32 and rates.shape == targets.shape
assert np.isfinite(rates).all() and np.all(rates >= 0) and steps == 1000
original = rates * .1 / 1000.0
explicit = rates * np.float32(.1) / np.float32(1000.)
assert original.dtype == np.float32 and np.array_equal(original.view(np.uint32), explicit.view(np.uint32))
assert np.all(original <= 1)
generator = torch.Generator(device='cuda')
generator.manual_seed(int(seed))
probabilities = torch.as_tensor(original, dtype=torch.float32, device='cuda')
forced = (torch.rand((steps, len(targets)), generator=generator, device='cuda') < probabilities[None, :]).cpu().numpy()
return requests_from_forced(forced, targets)
def write_npz(path, **arrays):
with Path(path).open('xb') as stream:
np.savez_compressed(stream, **arrays)
@@ -0,0 +1,170 @@
"""Recompute the new evidence, preserve gated non-execution, then seal truthfully."""
from context import ROOT, MODEL, EXP, AJ, AJ_MODEL, AG, CFG, read, save, digest, check, integrity, budget, seal
def optional(path):
return read(path) if path.exists() else None
def decide_status(*, numerical, seed, novel, integrity_pass, reference_pass, reference_present,
known_numerical_failure=False, unauthorized_novel=False):
if not integrity_pass or (reference_present and not reference_pass):
return 'FAIL-FROZEN-INTEGRITY-OR-REGRESSION'
if known_numerical_failure or unauthorized_novel:
return 'FAIL-NUMERICAL-OR-EXECUTION-POLICY'
if not numerical or not reference_present or not seed or not seed['execution_gate_pass']:
return 'INCOMPLETE-VALIDATION-EXECUTION'
if not seed['representation_gate_pass']:
return 'FAIL-SEED-VALIDATION-REPRESENTATION'
if not novel or not novel['execution_gate_pass']:
return 'INCOMPLETE-VALIDATION-EXECUTION'
if not novel['representation_gate_pass']:
return 'FAIL-NOVEL-ODOR-REPRESENTATION'
return 'PASS-FROZEN-D18-INDEPENDENT-VALIDATION'
def component_report(group, name):
path = EXP / 'component-audit' / group / (name + '.json')
if not path.exists():
return None
report = read(path)
output = EXP / 'gpu' / group / (name + '-r0')
assert set(report.get('input_sha256', {})) == {'state.npz', 'summary.json',
'apl-drive.float32.npy', 'apl-state.float32.npy', 'apl-inhibition.float32.npy'}
for filename, checksum in report['input_sha256'].items():
assert digest(output / filename) == checksum
assert set(report.get('matrix_checks', {})) == {'input_matrix', 'output_matrix', 'input_raw', 'output_raw',
'kc_globals', 'apl_globals', 'pn_globals', 'apl_out_ids', 'input_scale', 'output_scale'}
assert set(report.get('ast_replay_bitwise_exact', {})) == {'drive', 'state', 'inhibition'}
assert set(report.get('float64_measurement', {})) == {'drive', 'state', 'inhibition'}
actual = bool(not report.get('error') and all(report['matrix_checks'].values()) and
all(report['ast_replay_bitwise_exact'].values()) and report['theoretical_bound']['applicable'] and
all(value['bound_violations'] == 0 for value in report['float64_measurement'].values()))
assert report['pass_all'] == actual
return actual
def main():
from pathlib import Path
import runtime_bridge as bridge
from validation import summarize
check(); budget()
controls_inventory, records = bridge.inventories(EXP, CFG)
controls, comparisons, components, repeats, summaries = {}, {}, {}, {}, {}
for row in controls_inventory:
name = row['name']
path = EXP / 'audit' / ('control-' + name + '.json')
if path.exists():
actual = bridge.control_identity(EXP / 'gpu/controls' / (name + '-r0'), Path(row['source_output']),
EXP / 'cases/controls' / name, Path(row['source_case']), None)
assert actual == read(path), 'Raw control evidence changed'
controls[name] = actual['pass_all']
component = component_report('controls', name)
if component is not None:
components['controls/' + name] = component
gates = {stage: optional(EXP / 'audit' / (stage + '-gate.json')) for stage in bridge.STAGES}
for cohort in CFG['validation']['cohorts']:
summary_path = EXP / 'validation' / cohort / 'summary.json'
if summary_path.exists():
actual = summarize(cohort, out_json=None)
assert actual == read(summary_path), 'Raw validation evidence changed: ' + cohort
summaries[cohort] = actual
for row in bridge.probe_rows(records, CFG, cohort):
name = row['name']
path = EXP / 'audit' / ('compare-' + cohort + '-' + name + '.json')
if path.exists():
actual = bridge.compare(EXP / 'cases' / cohort / name, EXP / 'gpu' / cohort / (name + '-r0'),
EXP / 'oracle' / cohort / name, None)
assert actual == read(path), 'Raw oracle evidence changed'
comparisons[cohort + '/' + name] = actual['pass_all']
component = component_report(cohort, name)
if component is not None:
components[cohort + '/' + name] = component
for row in bridge.cohort_rows(records, CFG, cohort):
if row['seed'] != CFG['validation']['seeds'][0]:
continue
name = row['name']
path = EXP / 'audit' / ('repeat-' + cohort + '-' + name + '.json')
if path.exists():
actual = bridge.compare_gpu_repeats(EXP / 'gpu' / cohort / (name + '-r0'),
EXP / 'gpu' / cohort / (name + '-r1'), None)
assert actual == read(path), 'Raw repeat evidence changed'
repeats[cohort + '/' + name] = actual['pass_all']
seed, novel = summaries.get('seed_validation'), summaries.get('novel_to_aj')
seed_pass = bool(seed and seed['execution_gate_pass'] and seed['representation_gate_pass'])
novel_paths = [str(path.relative_to(EXP)) for root in ('gpu', 'oracle', 'component-audit')
for path in (EXP / root / 'novel_to_aj').glob('*')]
unauthorized = bool(novel_paths and not seed_pass)
required_cohorts = ['seed_validation', 'novel_to_aj'] if seed_pass else ['seed_validation']
expected_controls = {row['name'] for row in controls_inventory}
expected_comparisons = {cohort + '/' + row['name'] for cohort in required_cohorts
for row in bridge.probe_rows(records, CFG, cohort)}
expected_components = expected_comparisons | {'controls/' + name for name in expected_controls}
expected_repeats = {cohort + '/' + row['name'] for cohort in required_cohorts
for row in bridge.cohort_rows(records, CFG, cohort) if row['seed'] == CFG['validation']['seeds'][0]}
required_stages = ['controls', 'seed-probes', 'seed-validation'] + (['novel-probes', 'novel-validation'] if seed_pass else [])
numerical = bool(set(controls) == expected_controls and set(comparisons) == expected_comparisons and
set(components) == expected_components and set(repeats) == expected_repeats and
all(all(values.values()) for values in (controls, comparisons, components, repeats)) and
all(gates[stage] and gates[stage]['pass_all'] for stage in required_stages) and
all(cohort in summaries and summaries[cohort]['execution_gate_pass'] for cohort in required_cohorts))
for cohort, summary in summaries.items():
stage = 'seed-validation' if cohort == 'seed_validation' else 'novel-validation'
if gates[stage]:
assert gates[stage]['execution_gate_pass'] == summary['execution_gate_pass']
assert gates[stage]['representation_gate_pass'] == summary['representation_gate_pass']
frozen = optional(EXP / 'regression/frozen-five.json')
integrity_result = integrity()
save(EXP / 'regression/old-integrity-after.json', integrity_result)
oldpass = all(row['pass'] for row in integrity_result.values())
failures = [read(path) for path in sorted((EXP / 'audit').glob('stopped-*.json'))]
known_failure = bool(any(not value for group in (controls, comparisons, components, repeats) for value in group.values()) or
any(gate is not None and not gate['pass_all'] for gate in gates.values()) or
any(not summary['execution_gate_pass'] for summary in summaries.values()) or
any(row.get('stop_kind') == 'execution_or_numerical_failure' for row in failures))
status = decide_status(numerical=numerical, seed=seed, novel=novel, integrity_pass=oldpass,
reference_present=frozen is not None, reference_pass=bool(frozen and frozen['pass_all']),
known_numerical_failure=known_failure, unauthorized_novel=unauthorized)
present_runs = []
for path in sorted((EXP / 'gpu').glob('*/*/summary.json')):
value = read(path)
present_runs.append(dict(group=path.parent.parent.name, run=path.parent.name,
complete=value.get('complete', False), pass_all=value.get('pass_all', False),
**{key: value.get(key) for key in ('case', 'nodes', 'edges', 'total_spikes',
'diagnostic_simulation_seconds', 'peak_allocated_vram_bytes')}))
completed_primary = [row for row in present_runs if row['group'] in CFG['validation']['cohorts']
and row['run'].endswith('-r0') and row['complete']]
result = dict(status=status, numerical_gate_pass=numerical, summaries=summaries, gates=gates,
controls=controls, comparisons=comparisons, components=components, repeats=repeats, stopped=failures,
seed_validation_pass=seed_pass, novel_to_aj_pass=bool(novel and novel['pass_all']),
novel_dynamics_executed=bool(novel_paths), novel_unlock_policy_violation=unauthorized,
planned_primary_cases=120, actual_primary_cases=len(completed_primary), measurements=present_runs,
aggregated_valid_primary_cases=sum(summary['valid_base_trials'] for summary in summaries.values()),
actual_checked_repeats=sum(summary['checked_repeats'] for summary in summaries.values()),
old_frozen_integrity_pass=oldpass, frozen_five_reference_pass=bool(frozen and frozen['pass_all']),
unchanged_sealed_runtime=True, dynamics_changed=False, old_heldout_dynamic_results_parsed=False,
novel_scope='Unused for AG/AJ calibration, not historically never simulated',
shared_APL_arithmetic_oracle_limitation=True, biological_delay_measured=False,
APL_nonKC_fast_edges_unreplaced=1212, learning_achieved=False, candidate_generated=False,
full_scientific_goal_achieved=False, payload_bytes_before_manifest=budget(),
next_gate='Credit specificity and real KC-to-MBON functional transfer before conditioning' if status.startswith('PASS-')
else 'Inspect the first failed gate without tuning this frozen branch or replacing validation inputs')
save(EXP / 'audit/final-status.json', result)
with (EXP / 'REPORT.md').open('x', encoding='utf-8') as stream:
stream.write('\n'.join(['# Phase 4AK — frozen D18 independent validation', '', f'Status: `{status}`.', '',
f'Numerical gate: {numerical}. Seed-validation pass: {seed_pass}. Novel-to-AJ pass: {result["novel_to_aj_pass"]}.',
f'Novel dynamics executed: {bool(novel_paths)}. Unauthorized unlock: {unauthorized}.',
'Both cohorts and all requested inputs were locked before trajectories; no tuning or gate changes.',
'Original sealed AJ runtime functions are used unchanged, including 1,212 unreplaced non-KC APL fast edges.',
'The second six odors were not used for AG/AJ calibration; old 4L had simulated the full panel.',
'Static seed audit is bounded, not proof of universally unused or statistically independent RNG streams.',
'Brian LIF/FIFO is independent; APL arithmetic is intentionally shared and separately component-audited.',
f'Old frozen integrity: {oldpass}. Five old reference trials: {result["frozen_five_reference_pass"]}.',
'No learning, plasticity update, candidate, game, decoder, RL or Web. This is not completion of the learning goal.',
'Next gate: ' + result['next_gate'], '']))
check(); seal(MODEL); seal(EXP)
print(status, flush=True)
if __name__ == '__main__':
main()
@@ -0,0 +1,90 @@
{
"root": "/data/digital-drosophila/models/male-cns-lif/apl-timing-validation-v1",
"files": [
{
"path": "PROTOCOL.md",
"bytes": 5002,
"sha256": "2d3996933b6e5a31e6a737ade5f3ae6869ffd03e01002c793eccf9b4f71e987d"
},
{
"path": "SEED-AUDIT.md",
"bytes": 6540,
"sha256": "35e8bfe1bff62f3a5d9295c785e1b8cec8a2393eaa67d6c683046e48f30feb56"
},
{
"path": "config.json",
"bytes": 2183,
"sha256": "1718d8b01ece24930ff138f25c88f2f0e0f1cf69ad0ba655e5a0de5083e64df2"
},
{
"path": "context.py",
"bytes": 5834,
"sha256": "5e4e500d5ec777bb8ae7ff77ac9a7279bfe995b1a17be2baededdbe065c98b73"
},
{
"path": "encoder_inputs.py",
"bytes": 2431,
"sha256": "0061689abb1832e963718bd836bc8a50009ee38b258143a753b4d59e63414925"
},
{
"path": "finalize.py",
"bytes": 11542,
"sha256": "7eb638c357cec7f5f85032312c50a616402b5a8a9ab5aa0268c181f6c3ae0ce5"
},
{
"path": "prepare.py",
"bytes": 12405,
"sha256": "d8b8315f8800b3efdc7548620f0fae85da21a12b753b9985dd623bd529e2c50f"
},
{
"path": "run_case.py",
"bytes": 3382,
"sha256": "bba6c4a98c6edf1eaba60b8030a9eca646da7dd30b74b2a0c16e374efd022bfa"
},
{
"path": "run_suite.py",
"bytes": 7914,
"sha256": "3d9890f11f299c07956faa5c0a9ebe2ea28ade58d8acf01a8631c17025073345"
},
{
"path": "runtime_bridge.py",
"bytes": 22443,
"sha256": "8a6629f8cd991cf309b508c670b3009737f9b5f5e1f72560fa5bd4b1ff0bc64d"
},
{
"path": "seed-audit.json",
"bytes": 376926,
"sha256": "e14c0deb94432787aa1cac7618254aeb3db0bcd5b1d8328e20428496d38b220a"
},
{
"path": "test_encoder_inputs.py",
"bytes": 2771,
"sha256": "f1b3b8a0ca9bc41152485c05fd5f24fb7bb1f76c6ea111ffb941ae1225d914fe"
},
{
"path": "test_final_status.py",
"bytes": 2040,
"sha256": "a85466891352c15b3103d30e7229734ad6694c8a1347d5e0747da3315223c203"
},
{
"path": "test_runtime_bridge.py",
"bytes": 23574,
"sha256": "bc01a5ff38d79a7b66ab2eb9e6731164bb8a1e15b5b5c0c1655161c24e2c37cf"
},
{
"path": "test_validation.py",
"bytes": 17829,
"sha256": "03f5aacb5a1f9460d10b30744100a43c57e5488d32dada79c888529943c82cf0"
},
{
"path": "validation.py",
"bytes": 21631,
"sha256": "3464091a4cc2cba18946cb9c9b3d12a69bd3f79f1001096234b3a8467dc602c5"
},
{
"path": "verify_frozen.py",
"bytes": 2417,
"sha256": "a736b774e39ff0ad863e8efc720bd5f9ed7d30261776bb57f0a716a7052dba5a"
}
]
}
@@ -0,0 +1,180 @@
"""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()
@@ -0,0 +1,66 @@
"""One registered AK action per fresh process; no changes to frozen runtimes."""
import argparse
import json
import os
import urllib.request
from context import ROOT, EXP, CFG, check, budget, read
import runtime_bridge as bridge
def preflight():
# Establish visibility before the lazy runtime/component Torch import.
os.environ['CUDA_VISIBLE_DEVICES'] = CFG['gpu_uuid']
os.environ['CUDA_HOME'] = '/usr/local/cuda'
os.environ['PATH'] = str(ROOT / 'models/male-cns-lif/.venv/bin') + ':/usr/local/cuda/bin:' + os.environ['PATH']
os.environ['MAX_JOBS'] = '2'
os.environ['TORCH_CUDA_ARCH_LIST'] = '8.9'
for port in (8188, 8189, 8190):
with urllib.request.urlopen(f'http://192.168.10.51:{port}/queue', timeout=5) as response:
queue = json.load(response)
bridge.require(not queue['queue_running'] and not queue['queue_pending'], 'ComfyUI busy: defer, never evict')
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('backend', choices=['gpu', 'oracle', 'component'])
parser.add_argument('group', choices=bridge.GROUPS)
parser.add_argument('case')
parser.add_argument('--repeat', type=int, default=0)
args = parser.parse_args()
check(); budget()
row = bridge.authorize_case(EXP, CFG, args.group, args.case, args.backend, args.repeat)
case = EXP / 'cases' / args.group / args.case
spec = bridge.case_spec(case)
bridge.require(spec['name'] == args.case and spec['budget_root'] == str(EXP) and
spec['output_budget_bytes'] == CFG['output_budget_bytes'], 'Case identity/new budget differs')
if args.group == 'controls':
bridge.control_inputs(case, row['source_case'])
else:
bridge.require(spec.get('kind') == 'fullgraph' and spec.get('validation_cohort') == args.group and
all(spec[key] == row[key] for key in ('mode', 'odor_id', 'odor_index', 'seed')),
'New fullgraph case differs from its registered cohort cell')
output = EXP / 'gpu' / args.group / f'{args.case}-r{args.repeat}'
if args.backend == 'component':
summary = read(output / 'summary.json')
bridge.require(summary.get('complete') is True and summary.get('pass_all') is True and
summary.get('case') == args.case and summary.get('apl_delay_steps') == 18,
'Component audit needs a complete matching D18 GPU run')
preflight()
def execute():
if args.backend == 'gpu':
result = bridge.run_gpu(case, output, EXP / 'extension-build')
elif args.backend == 'oracle':
result = bridge.run_oracle(case, EXP / 'oracle' / args.group / args.case)
else:
result = bridge.component(output, spec['apl_bundle_dir'], EXP / 'component-audit' / args.group / (args.case + '.json'))
budget()
bridge.require(result.get('pass_all') is True, 'Runtime/component evidence did not pass its own integrity checks')
return result
result = bridge.guarded_action(EXP, args.backend, args.group, args.case, args.repeat, execute)
print(json.dumps(dict(backend=args.backend, group=args.group, case=args.case, repeat=args.repeat,
complete=result.get('complete'), pass_all=result.get('pass_all')), allow_nan=False), flush=True)
if __name__ == '__main__':
main()
@@ -0,0 +1,151 @@
"""Ordered fixed-D18 validation; representation failure never becomes execution failure.
Only the two predeclared first-odor/first-seed mode probes use Brian per cohort.
Their GPU r0 outputs are reused in the full 60-case block. No novel-to-AJ
trajectory can start until the complete seed block and its repeats pass.
"""
import argparse
import subprocess
import time
import traceback
from context import ROOT, MODEL, EXP, CFG, check, save, read, budget
import runtime_bridge as bridge
SCIENCE = ROOT / 'models/male-cns-lif/.venv/bin/python'
ORACLE = ROOT / 'experiments/phase4ad-author-semantics/environment/.venv/bin/python'
class RepresentationGateFailed(RuntimeError):
"""Completed valid trajectories did not pass the predeclared representation gate."""
def child(backend, group, name, repeat=0):
# Do not resolve either interpreter: the venv invocation path is meaningful.
interpreter = ORACLE if backend == 'oracle' else SCIENCE
bridge.require(interpreter.is_file(), 'Missing fixed runtime interpreter: ' + str(interpreter))
bridge.authorize_case(EXP, CFG, group, name, backend, repeat)
log = EXP / 'logs' / f'{backend}-{group}-{name}-r{repeat}.log'
log.parent.mkdir(parents=True, exist_ok=True)
command = [str(interpreter), '-B', str(MODEL / 'run_case.py'), backend, group, name, '--repeat', str(repeat)]
print('START', backend, group, name, repeat, flush=True)
started = time.perf_counter()
with log.open('x', encoding='utf-8') as stream:
result = subprocess.run(command, stdout=stream, stderr=subprocess.STDOUT, timeout=1800, check=False)
print('FINISH', backend, group, name, repeat, 'exit', result.returncode,
'wall', round(time.perf_counter() - started, 2), flush=True)
bridge.require(result.returncode == 0, f'{backend} {group}/{name} failed; preserve partial evidence and inspect {log}')
def control(row):
name = row['name']
child('gpu', 'controls', name)
case = EXP / 'cases/controls' / name
output = EXP / 'gpu/controls' / (name + '-r0')
report = bridge.control_identity(output, row['source_output'], case, row['source_case'],
EXP / 'audit' / ('control-' + name + '.json'))
bridge.require(report['pass_all'], 'Fresh fixed-D18 control differs from sealed AJ: ' + name)
child('component', 'controls', name)
return dict(case=name, group='controls', pass_all=True, fresh_gpu_runs=1, new_oracle_runs=0)
def probe(row):
name, group = row['name'], row['cohort']
child('gpu', group, name)
child('oracle', group, name)
result = bridge.compare(EXP / 'cases' / group / name, EXP / 'gpu' / group / (name + '-r0'),
EXP / 'oracle' / group / name, EXP / 'audit' / ('compare-' + group + '-' + name + '.json'))
bridge.require(result['pass_all'], 'Closed-loop fixed-D18 comparison failed: ' + name)
child('component', group, name)
return dict(case=name, group=group, pass_all=True, fresh_gpu_runs=1, new_oracle_runs=1)
def validation_block(cohort, records):
from validation import summarize
rows = bridge.cohort_rows(records, CFG, cohort)
probes = {row['name'] for row in bridge.probe_rows(records, CFG, cohort)}
repeated = []
for row in rows:
name = row['name']
if name not in probes:
child('gpu', cohort, name)
else:
comparison = read(EXP / 'audit' / ('compare-' + cohort + '-' + name + '.json'))
bridge.require(comparison.get('pass_all') is True and comparison.get('case') == name,
'Missing successful probe evidence for reused r0: ' + name)
if row['seed'] == CFG['validation']['seeds'][0]:
child('gpu', cohort, name, 1)
result = bridge.compare_gpu_repeats(EXP / 'gpu' / cohort / (name + '-r0'),
EXP / 'gpu' / cohort / (name + '-r1'), EXP / 'audit' / ('repeat-' + cohort + '-' + name + '.json'))
bridge.require(result['pass_all'], 'Fixed-input GPU repeat diverged: ' + name)
repeated.append(name)
bridge.require(len(rows) == 60 and len(repeated) == 12, 'Incomplete registered base/repeat block')
result = summarize(cohort)
return result, repeated
def run(stage):
bridge.require(stage in bridge.STAGES, 'Unknown stage')
check(); budget()
bridge.ensure_unstopped(EXP)
receipt = EXP / 'audit' / (stage + '-gate.json')
bridge.require(not receipt.exists() and not (EXP / 'audit' / ('stopped-' + stage + '.json')).exists(),
'Stage already has completion/stop evidence; do not rerun or overwrite')
controls, records = bridge.inventories(EXP, CFG)
try:
if stage == 'controls':
rows = [control(row) for row in controls]
result = dict(stage=stage, pass_all=True, cases=rows, scope='Same-input fresh D18 GPU identity with sealed AJ; no new model or Brian run')
else:
bridge.gate_pass(EXP, 'controls')
cohort = 'seed_validation' if stage.startswith('seed-') else 'novel_to_aj'
if cohort == 'novel_to_aj':
bridge.gate_pass(EXP, 'seed-validation', representation=True, cfg=CFG)
if stage.endswith('-probes'):
rows = [probe(row) for row in bridge.probe_rows(records, CFG, cohort)]
result = dict(stage=stage, pass_all=True, cases=rows,
scope='Two fixed first-odor first-seed mode probes; independent LIF with shared unchanged Torch APL component')
else:
bridge.gate_pass(EXP, 'seed-probes' if cohort == 'seed_validation' else 'novel-probes')
summary, repeats = validation_block(cohort, records)
execution = summary.get('execution_gate_pass') is True
representation = summary.get('representation_gate_pass') is True
if execution:
bridge.validate_summary_coverage(summary, EXP, CFG, cohort)
result = dict(stage=stage, cohort=cohort, pass_all=execution,
execution_gate_pass=execution, representation_gate_pass=representation,
base_count=60, repeat_count=len(repeats), repeat_cases=repeats,
summary='validation/' + cohort + '/summary.json',
summary_sha256=bridge.digest(EXP / 'validation' / cohort / 'summary.json'),
validation_inventory_sha256=bridge.digest(EXP / 'protocol/validation-cases.json'),
scope='Complete fixed representation block; no pooled rescue, learning, tuning, or historically-unseen-odor claim')
save(receipt, result)
if stage.endswith('-validation'):
bridge.require(result['execution_gate_pass'], 'Validation execution/numerical/integrity gate failed')
if not result['representation_gate_pass']:
raise RepresentationGateFailed('Completed fixed validation block failed representation; no later cohort is authorized')
budget()
return result
except Exception as error:
save(EXP / 'audit' / ('stopped-' + stage + '.json'), dict(stage=stage,
type=type(error).__name__, message=str(error), traceback=traceback.format_exc(),
stop_kind='representation_failure' if isinstance(error, RepresentationGateFailed) else 'execution_or_numerical_failure',
representation_failure_is_execution_failure=False,
later_stages_not_permitted=True, partial_outputs_preserved=True,
parameters_changed=False, replacement_seeds_or_odors_selected=False))
raise
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('stage', choices=bridge.STAGES)
args = parser.parse_args()
try:
run(args.stage)
except RepresentationGateFailed:
raise SystemExit(2)
if __name__ == '__main__':
main()
@@ -0,0 +1,396 @@
"""Phase 4AK orchestration only: call hash-pinned, unchanged AJ functions.
No LIF, APL, queue, or input-generation equation is implemented here. Fresh
processes resolve AJ's one unqualified import to the pinned AJ timing_queue.
The D18 control adapter compares evidence; it never changes a case to D0.
"""
from __future__ import annotations
import hashlib
import importlib.util
import json
from pathlib import Path
import re
import sys
import traceback
AJ_PINS = {
'gpu_timing.py': 'af1975ba5e5e700208c0a598d3cbe648a3cf10885c6231239b6e4b28f76d173b',
'oracle_timing.py': '39d8c47c94bc2faddf016864a43e7715907fb987f56f7b27098060a88851f6be',
'compare_timing.py': '9010f070fba9b7c9cf2d86187ee2abc57f3ac606ebc08a42baad4f3922b51734',
'timing_queue.py': '54df6d4818e2a0c26e96fb0aaf5d9b71cd964981706da937562d48af79aca14e',
}
COMPONENT_SHA256 = '5cfc9a4505da6b8fb4e7d2617cdaedaa8475ed46a11ec9bdf0d4d25b1d22c2d3'
COHORTS = ('seed_validation', 'novel_to_aj')
GROUPS = ('controls',) + COHORTS
STAGES = ('controls', 'seed-probes', 'seed-validation', 'novel-probes', 'novel-validation')
_BUDGET_KEYS = frozenset(('budget_root', 'output_budget_bytes'))
_LOADED = {}
def require(ok, message):
if not ok:
raise ValueError(message)
def read(path):
return json.loads(Path(path).read_text(encoding='utf-8'))
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 save(path, report):
if path is None:
return
path = Path(path)
path.parent.mkdir(parents=True, exist_ok=True)
with path.open('x', encoding='utf-8') as stream:
json.dump(report, stream, ensure_ascii=False, indent=2, sort_keys=True, allow_nan=False)
stream.write('\n')
def load_checked(name, path, expected_hash):
"""Execute the verified bytes with importlib metadata, without old pyc writes."""
path = Path(path).absolute()
data = path.read_bytes()
require(hashlib.sha256(data).hexdigest() == expected_hash, 'Sealed source SHA mismatch: ' + str(path))
if name in sys.modules:
existing = sys.modules[name]
require(Path(getattr(existing, '__file__', '')).absolute() == path and
_LOADED.get(name) == (path, expected_hash, existing),
'Refusing an existing unverified module name: ' + name)
return existing
spec = importlib.util.spec_from_file_location(name, path)
require(spec is not None and spec.loader is not None, 'Cannot create sealed module specification')
module = importlib.util.module_from_spec(spec)
sys.modules[name] = module
try:
exec(compile(data, str(path), 'exec'), module.__dict__)
except BaseException:
sys.modules.pop(name, None)
raise
# Keep verification metadata here, not in the sealed module's globals.
_LOADED[name] = (path, expected_hash, module)
return module
def sealed(filename, aj_model=None):
require(filename in AJ_PINS, 'Unregistered AJ module')
if aj_model is None:
from context import AJ_MODEL
aj_model = AJ_MODEL
directory = Path(aj_model)
if filename == 'gpu_timing.py':
load_checked('timing_queue', directory / 'timing_queue.py', AJ_PINS['timing_queue.py'])
name = 'phase4ak_sealed_aj_' + Path(filename).stem
return load_checked(name, directory / filename, AJ_PINS[filename])
def case_spec(case_dir):
spec = read(Path(case_dir) / 'spec.json')
require(isinstance(spec.get('name'), str) and re.fullmatch(r'[A-Za-z0-9_-]+', spec['name']), 'Unsafe case name')
require(type(spec.get('apl_delay_steps')) is int and spec['apl_delay_steps'] == 18, 'AK permits fixed D18 only')
require(spec.get('steps') == 1000 and type(spec['steps']) is int and spec.get('dt_ms') == .1 and
spec.get('duration_ms') == 100.0 and spec.get('record_history') is False,
'AK requires the unchanged fullgraph 100 ms window')
require(spec.get('training') is False and spec.get('poi_used', False) is False and
spec.get('precision') == 'float64' and spec.get('apl_precision') == 'float32',
'Frozen no-learning / no-poi / precision scope changed')
require(spec.get('apl') == {'tau_ms': 20, 'gain': .01, 'normalization': 1}, 'Frozen APL parameters changed')
for field in ('graph_dir', 'apl_bundle_dir', 'coefficients_path', 'science_python', 'legacy_apl_worker'):
require(field in spec and Path(spec[field]).is_absolute(), 'Missing absolute path: ' + field)
require(isinstance(spec.get('model'), dict), 'Missing original author parameter dictionary')
return spec
def _new_output(case_dir, out_dir):
spec = case_spec(case_dir)
output = Path(out_dir).absolute()
budget_root = Path(spec['budget_root']).absolute()
require(type(spec.get('output_budget_bytes')) is int and spec['output_budget_bytes'] > 0,
'Missing positive output budget')
require(output.is_relative_to(budget_root) and output != budget_root and not output.exists(),
'Output must be a new exclusive child of this case budget root')
return spec
def _receipt(output, backend, filename, aj_model):
module = sealed(filename, aj_model)
require(digest(module.__file__) == AJ_PINS[filename], 'Sealed runtime changed during invocation')
receipt = {'backend': backend, 'sealed_runtime': str(module.__file__),
'sealed_runtime_sha256': AJ_PINS[filename], 'apl_delay_steps': 18,
'old_module_scientific_globals_changed': False, 'dynamics_copied_or_reimplemented': False,
'scope': 'Unchanged AJ runtime called with new case/output/build arguments; not a new numerical model'}
save(Path(output) / 'runtime-bridge.json', receipt)
def run_gpu(case_dir, out_dir, build_root, *, aj_model=None):
spec = _new_output(case_dir, out_dir)
build_root = Path(build_root).absolute()
require(build_root.is_relative_to(Path(spec['budget_root']).absolute()) and
build_root != Path(spec['budget_root']).absolute(), 'Build cache must stay in the new experiment')
module = sealed('gpu_timing.py', aj_model)
result = module.run_gpu(Path(case_dir), Path(out_dir), build_root)
_receipt(out_dir, 'gpu', 'gpu_timing.py', aj_model)
return result
def run_oracle(case_dir, out_dir, *, aj_model=None):
_new_output(case_dir, out_dir)
require('torch' not in sys.modules, 'Pinned Brian process must not import Torch')
module = sealed('oracle_timing.py', aj_model)
result = module.run_case(Path(case_dir), Path(out_dir))
_receipt(out_dir, 'oracle', 'oracle_timing.py', aj_model)
return result
def compare(case_dir, gpu_dir, cpu_dir, out_json=None, *, aj_model=None):
case_spec(case_dir)
return sealed('compare_timing.py', aj_model).compare(case_dir, gpu_dir, cpu_dir, out_json)
def compare_gpu_repeats(first, second, out_json=None, *, aj_model=None):
require(all(read(Path(path) / 'summary.json').get('apl_delay_steps') == 18 for path in (first, second)),
'Repeat evidence must be fixed D18')
return sealed('compare_timing.py', aj_model).compare_gpu_repeats(first, second, out_json)
def component(output, bundle, out_json, *, ag_model=None):
if ag_model is None:
from context import AG_MODEL
ag_model = AG_MODEL
module = load_checked('phase4ak_sealed_ag_components', Path(ag_model) / 'validate_components.py', COMPONENT_SHA256)
return module.validate(Path(output), Path(bundle), Path(out_json))
def control_inputs(newcase, oldcase):
"""Only budget metadata may differ; all saved request/drive bytes are identical."""
newcase, oldcase = Path(newcase), Path(oldcase)
fresh, old = case_spec(newcase), case_spec(oldcase)
require({k: v for k, v in fresh.items() if k not in _BUDGET_KEYS} ==
{k: v for k, v in old.items() if k not in _BUDGET_KEYS},
'D18 control scientific specification changed beyond the two budget fields')
evidence = {str(folder / 'spec.json'): digest(folder / 'spec.json') for folder in (newcase, oldcase)}
files = ['requests.npz', 'pn-drive.npz']
require((newcase / 'arrays.npz').exists() == (oldcase / 'arrays.npz').exists(), 'Control initial-state presence changed')
if (newcase / 'arrays.npz').exists():
files.append('arrays.npz')
for name in files:
first, second = digest(newcase / name), digest(oldcase / name)
require(first == second, 'Control input byte mismatch: ' + name)
evidence[str(newcase / name)], evidence[str(oldcase / name)] = first, second
return fresh, old, evidence
def control_identity(newdir, olddir, newcase, oldcase, out_json=None, *, aj_model=None):
"""D18 scientific identity using unchanged AJ comparison primitives.
Unlike the AJ D0-vs-AG adapter, this checks real D18 applied/pending files.
Input SHA fields are checked against each real spec, not compared after
deleting metadata. Only build/cache paths and the two budget fields are
permitted to differ; all numerical/timing/component evidence stays exact.
"""
require(out_json is None or not Path(out_json).exists(), 'Refusing existing control report')
aj = sealed('compare_timing.py', aj_model)
checks, differences, used = {}, {}, set()
report = {'kind': 'fixed-D18 same-input sealed-AJ control identity', 'pass_all': False,
'new_output': str(newdir), 'old_output': str(olddir), 'new_case': str(newcase), 'old_case': str(oldcase),
'apl_delay_steps': 18, 'tolerance': None, 'signed_zero_included': True,
'dynamics_copied_or_reimplemented': False, 'old_globals_patched': False,
'independent_CPU_all_components_claim': False,
'allowed_case_metadata_differences': sorted(_BUDGET_KEYS),
'build_and_wall_metadata_compared': False}
try:
spec, old_spec, inputs = control_inputs(newcase, oldcase)
used.update(Path(path) for path in inputs)
checks['control_input_spec_and_bytes'] = True
steps, n, edges = spec['steps'], 166700, 25582938
left = aj._load_run(Path(newdir), 'fresh_gpu', n, edges, steps, False, spec['name'], 18, used, checks)
right = aj._load_run(Path(olddir), 'sealed_gpu', n, edges, steps, False, spec['name'], 18, used, checks)
aj._pair_outputs(left, right, checks, differences, n, steps, False)
for role, run, case, case_input in (('fresh_gpu', left, Path(newcase), spec),
('sealed_gpu', right, Path(oldcase), old_spec)):
aj._timing_sequence_checks(run['apl']['inhibition'], run['apl']['applied'], run['pending'],
18, role, checks, differences)
aj._timing_metadata_checks(run, role, 18, steps, checks)
expected = {name: digest(case / name) for name in ('spec.json', 'requests.npz')}
if (case / 'arrays.npz').exists():
expected['arrays.npz'] = digest(case / 'arrays.npz')
weight, coeff = Path(case_input['graph_dir']) / 'weights.npy', Path(case_input['coefficients_path'])
used.update((weight, coeff))
expected.update({'base_weights.npy': digest(weight), 'coefficients.json': digest(coeff)})
checks[role + '.actual_input_hashes'] = run['summary'].get('input_sha256') == expected
stable = ('case', 'complete', 'pass_all', 'steps', 'completed_ticks', 'nodes', 'edges', 'precision',
'apl_precision', 'state_units', 'total_spikes', 'requested', 'accepted_requests', 'rejected_requests',
'arriving_edges', 'accepted_arriving_edges', 'counts_match_sparse_events', 'all_finite', 'record_history',
'apl_fast_edges_zeroed', 'kc_targets_present', 'effective_weights_raw_sha256', 'apl_schedule',
'apl_si_conversion', 'sealed_ae_backend_sha256', 'learning', 'apl_delay_steps', 'apl_timing',
'source_provenance', 'pending_generated_count', 'pending_initial_zero_prefix', 'pending_tail_shape',
'future_generated_decay_tail_included')
for key in stable:
checks['summary.' + key] = key in left['summary'] and key in right['summary'] and left['summary'][key] == right['summary'][key]
checks['timing_audit.parsed_exact'] = left['timing'] == right['timing']
report.update(case=spec['name'], steps=steps, nodes=n, edges=edges,
scope='Six state arrays, every tick state/queue/request, generated/applied/pending APL, component and timing metadata')
except Exception as error:
report['error'] = {'type': type(error).__name__, 'message': str(error)}
return aj._finish(report, checks, differences, used, out_json)
def inventories(exp, cfg):
"""Validate static cells before choosing any dynamic case; no old dynamic read."""
exp = Path(exp)
controls = read(exp / 'protocol/control-cases.json')
records = read(exp / 'protocol/validation-cases.json')
require(isinstance(controls, list) and len(controls) == 2 and
[row['name'] for row in controls] == cfg['control_cases'], 'Unexpected control inventory')
for row in controls:
require(re.fullmatch(r'[A-Za-z0-9_-]+', row['name']) and
all(Path(row[key]).is_absolute() for key in ('source_case', 'source_output')), 'Invalid control identity/path')
design = cfg['validation']
require(design['cohorts'] == list(COHORTS) and len(design['seeds']) == 5 and len(set(design['seeds'])) == 5 and
design['modes'] == ['physiological', 'matched_energy'] and design['odor_count'] == 6 and
design['repeat_first_seed_each_odor'] is True, 'Fixed validation design changed')
require(isinstance(records, list) and len(records) == 120, 'Expected 120 predeclared cases')
cells, names = set(), set()
for row in records:
key = (row['cohort'], row['mode'], row['odor_index'], row['seed'])
require(re.fullmatch(r'[A-Za-z0-9_-]+', row['name']) and row['name'] not in names and key not in cells,
'Duplicate/unsafe case identity')
require(type(row['odor_index']) is int and type(row['seed']) is int, 'Noninteger odor/seed')
cells.add(key); names.add(row['name'])
expected = {(cohort, mode, oi, seed) for cohort in COHORTS for mode in design['modes']
for oi in range(6) for seed in design['seeds']}
require(cells == expected, 'Missing or substituted validation cell')
return controls, records
def cohort_rows(records, cfg, cohort):
require(cohort in COHORTS, 'Unknown validation cohort')
design = cfg['validation']
return sorted((row for row in records if row['cohort'] == cohort),
key=lambda row: (design['modes'].index(row['mode']), row['odor_index'], design['seeds'].index(row['seed'])))
def probe_rows(records, cfg, cohort):
rows = [row for row in cohort_rows(records, cfg, cohort)
if row['odor_index'] == 0 and row['seed'] == cfg['validation']['seeds'][0]]
require(len(rows) == 2 and [row['mode'] for row in rows] == cfg['validation']['modes'], 'Fixed probe selection changed')
return rows
def ensure_unstopped(exp):
markers = sorted((Path(exp) / 'audit').glob('stopped-*.json'))
require(not markers, 'A prior stop marker forbids all new scientific actions: ' + ', '.join(path.name for path in markers))
def guarded_action(exp, backend, group, name, repeat, action):
"""Persist failure after invoking an authorized scientific action, even standalone.
The caller performs input authorization and external idle preflight first.
A failure here is an execution/audit failure, not evidence of instability.
"""
require(backend in ('gpu', 'oracle', 'component') and group in GROUPS and
isinstance(name, str) and re.fullmatch(r'[A-Za-z0-9_-]+', name) and
type(repeat) is int and repeat in (0, 1), 'Invalid guarded action identity')
ensure_unstopped(exp)
try:
return action()
except Exception as error:
save(Path(exp) / 'audit' / f'stopped-case-{backend}-{group}-{name}-r{repeat}.json', {
'stage': 'case', 'backend': backend, 'group': group, 'case': name, 'repeat': repeat,
'type': type(error).__name__, 'message': str(error), 'traceback': traceback.format_exc(),
'stop_kind': 'execution_or_numerical_failure', 'scientific_action_invoked': True,
'numerical_instability_inferred_from_execution_error': False,
'later_stages_not_permitted': True, 'partial_outputs_preserved': True,
'parameters_changed': False, 'replacement_seeds_or_odors_selected': False})
raise
def validate_summary_coverage(summary, exp, cfg, cohort, *, representation=False):
"""Bind the unlock to this cohort's exact 60 base / 12 repeat / 72 timing cells."""
_, records = inventories(exp, cfg)
rows = cohort_rows(records, cfg, cohort)
expected = {row['name'] for row in rows}
repeated = {row['name'] for row in rows if row['seed'] == cfg['validation']['seeds'][0]}
timing = {(name, 0) for name in expected} | {(name, 1) for name in repeated}
require(summary.get('cohort') == cohort and summary.get('phase') == '4AK' and
summary.get('apl_delay_steps') == 18 and summary.get('seeds') == cfg['validation']['seeds'] and
summary.get('duration_ms') == 100.0, 'Validation summary identity/window differs')
require(summary.get('expected_base_trials') == summary.get('valid_base_trials') == 60 and
summary.get('expected_repeats') == summary.get('checked_repeats') == 12 and
summary.get('checked_timing_trials') == 72, 'Incomplete validation coverage')
base_rows, repeat_rows, timing_rows = (summary.get(key, []) for key in ('runs', 'repeats', 'timing_checks'))
require(len(base_rows) == 60 and {row['case'] for row in base_rows} == expected and
all(row.get('cohort') == cohort and row.get('validation_cohort') == cohort for row in base_rows),
'Base-trial identities differ from the fixed cohort inventory')
require(len(repeat_rows) == 12 and {row['case'] for row in repeat_rows} == repeated and
all(row.get('pass_all') is True for row in repeat_rows), 'Exact-repeat identities/coverage failed')
require(len(timing_rows) == 72 and {(row['case'], row['repeat']) for row in timing_rows} == timing and
all(type(row['repeat']) is int and row.get('pass_all') is True and row.get('apl_delay_steps') == 18
and row.get('steps') == 1000 for row in timing_rows), 'Timing identities/coverage failed')
proof = summary.get('input_output_provenance', [])
require(len(proof) == 72 and {(row['case'], row['repeat']) for row in proof} == timing,
'Per-run evidence provenance does not cover exactly the registered cells')
require(summary.get('prerequisite_input_sha256', {}).get('validation_inventory') ==
digest(Path(exp) / 'protocol/validation-cases.json'), 'Summary was derived from a different validation inventory')
require(summary.get('execution_gate_pass') is True and summary.get('numerical_integrity_pass') is True and
summary.get('exact_repeat_pass') is True, 'Validation execution/numerical/repeat gate failed')
require(set(summary.get('modes', {})) == set(cfg['validation']['modes']), 'Incomplete mode summaries')
if representation:
require(summary.get('representation_gate_pass') is True and summary.get('pass_all') is True and
all(summary['modes'][mode].get('gate') is True for mode in cfg['validation']['modes']),
'Seed representation summary does not authorize novel dynamics')
def gate_pass(exp, stage, *, representation=False, cfg=None):
report = read(Path(exp) / 'audit' / (stage + '-gate.json'))
require(report.get('stage') == stage and report.get('pass_all') is True, 'Required execution gate failed: ' + stage)
if representation:
require(stage == 'seed-validation', 'Only the complete seed block unlocks novel trajectories')
require(report.get('execution_gate_pass') is True and report.get('representation_gate_pass') is True,
'Complete seed representation/execution gate required before novel dynamics')
if cfg is None:
from context import CFG
cfg = CFG
path = Path(exp) / 'validation/seed_validation/summary.json'
require(report.get('cohort') == 'seed_validation' and
report.get('summary') == 'validation/seed_validation/summary.json' and
report.get('summary_sha256') == digest(path), 'Seed gate is not bound to this exact summary')
require(report.get('validation_inventory_sha256') == digest(Path(exp) / 'protocol/validation-cases.json'),
'Seed gate inventory digest differs')
validate_summary_coverage(read(path), exp, cfg, 'seed_validation', representation=True)
return report
def authorize_case(exp, cfg, group, name, backend, repeat):
ensure_unstopped(exp)
require(group in GROUPS and backend in ('gpu', 'oracle', 'component') and type(repeat) is int and repeat in (0, 1),
'Invalid runtime action')
controls, records = inventories(exp, cfg)
rows = controls if group == 'controls' else cohort_rows(records, cfg, group)
selected = [row for row in rows if row['name'] == name]
require(len(selected) == 1, 'Case not in the registered group inventory')
row = selected[0]
if group == 'controls':
require(repeat == 0 and backend in ('gpu', 'component'), 'Controls are single fresh GPU identity runs')
else:
gate_pass(exp, 'controls')
if group == 'novel_to_aj':
gate_pass(exp, 'seed-validation', representation=True, cfg=cfg)
probes = {item['name'] for item in probe_rows(records, cfg, group)}
probe_stage = 'seed-probes' if group == 'seed_validation' else 'novel-probes'
if name not in probes or repeat:
gate_pass(exp, probe_stage)
if backend in ('oracle', 'component'):
require(name in probes and repeat == 0, 'Oracle/component scope is the two fixed probes per cohort')
if repeat:
require(backend == 'gpu' and row['seed'] == cfg['validation']['seeds'][0], 'Only declared first-seed repeats')
return row
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,53 @@
import tempfile
import unittest
from pathlib import Path
import numpy as np
from encoder_inputs import frozen_pn_drive, requests_from_forced, write_npz
class EncoderInputTests(unittest.TestCase):
def test_exact_frozen_encoder_ast_on_synthetic_static_mapping(self):
import pandas as pd
local = Path(__file__).resolve().parents[1] / 'models/male-cns-lif/phase4l.py'
source = local if local.exists() else Path('/data/digital-drosophila/models/male-cns-lif/phase4l.py')
pin = 'e97d58d8c1f44920d0e953f8f5831ddc86fa0198784e86460e315de4116ac553'
function, ast_sha = frozen_pn_drive(source, pin)
self.assertEqual(len(ast_sha), 64)
mapping = pd.DataFrame(dict(glomerulus=['G2', 'G2', 'G1', 'G1'],
mapping_confidence=['exact', 'alias-normalized', 'exact', 'unknown'], neuron_idx=[3, 1, 7, 999]))
cfg = {'odor_encoder': {'max_total_rate_per_glomerulus_hz': 400}}
target, rates, _ = function('synthetic', np.array([.5, .25], np.float32), mapping,
['G2', 'G1'], 'matched_energy', 1.5, cfg)
np.testing.assert_array_equal(target, np.array([3, 1, 7], np.int32))
np.testing.assert_array_equal(rates, np.array([200, 200, 200], np.float32))
with self.assertRaises(AssertionError):
frozen_pn_drive(source, '0' * 64)
def test_rng_column_order_preserved_until_request_sort(self):
targets = np.array([10, 1, 3], np.int32)
forced = np.array([[True, True, False], [False, True, True]], np.bool_)
actual = requests_from_forced(forced, targets)
np.testing.assert_array_equal(actual, np.array([[0, 1], [0, 10], [1, 1], [1, 3]], np.int32))
np.testing.assert_array_equal(targets, np.array([10, 1, 3], np.int32))
def test_duplicate_targets_rejected_not_merged(self):
with self.assertRaises(AssertionError):
requests_from_forced(np.ones((2, 2), np.bool_), np.array([1, 1], np.int32))
def test_empty_sparse_schedule_has_exact_shape_and_dtype(self):
result = requests_from_forced(np.zeros((3, 2), np.bool_), np.array([2, 1], np.int32))
self.assertEqual(result.shape, (0, 2))
self.assertEqual(result.dtype, np.int32)
def test_npz_creation_is_exclusive(self):
with tempfile.TemporaryDirectory() as directory:
path = Path(directory) / 'schedule.npz'
write_npz(path, tick=np.array([1], np.int32))
with np.load(path, allow_pickle=False) as stored:
np.testing.assert_array_equal(stored['tick'], np.array([1], np.int32))
with self.assertRaises(FileExistsError):
write_npz(path, tick=np.array([2], np.int32))
if __name__ == '__main__':
unittest.main()
@@ -0,0 +1,39 @@
import unittest
from finalize import decide_status
class FinalStatusTests(unittest.TestCase):
def decide(self, **overrides):
args = dict(numerical=True, seed=dict(execution_gate_pass=True, representation_gate_pass=True),
novel=dict(execution_gate_pass=True, representation_gate_pass=True), integrity_pass=True,
reference_pass=True, reference_present=True)
args.update(overrides)
return decide_status(**args)
def test_complete_only_representation_pass_is_not_named_learning(self):
self.assertEqual(self.decide(), 'PASS-FROZEN-D18-INDEPENDENT-VALIDATION')
def test_seed_failure_without_novel_is_completed_scientific_failure(self):
self.assertEqual(self.decide(seed=dict(execution_gate_pass=True, representation_gate_pass=False), novel=None),
'FAIL-SEED-VALIDATION-REPRESENTATION')
def test_novel_gate_failure_is_preserved(self):
self.assertEqual(self.decide(novel=dict(execution_gate_pass=True, representation_gate_pass=False)),
'FAIL-NOVEL-ODOR-REPRESENTATION')
def test_missing_execution_or_reference_is_not_scientific_pass(self):
for changes in (dict(numerical=False), dict(novel=None), dict(reference_present=False), dict(seed=None)):
with self.subTest(changes=changes):
self.assertEqual(self.decide(**changes), 'INCOMPLETE-VALIDATION-EXECUTION')
def test_numerical_and_unlock_failure_are_not_representation_results(self):
self.assertEqual(self.decide(known_numerical_failure=True), 'FAIL-NUMERICAL-OR-EXECUTION-POLICY')
self.assertEqual(self.decide(unauthorized_novel=True), 'FAIL-NUMERICAL-OR-EXECUTION-POLICY')
def test_old_integrity_or_reference_fail_overrides_new_pass(self):
self.assertEqual(self.decide(integrity_pass=False), 'FAIL-FROZEN-INTEGRITY-OR-REGRESSION')
self.assertEqual(self.decide(reference_pass=False), 'FAIL-FROZEN-INTEGRITY-OR-REGRESSION')
if __name__ == '__main__':
unittest.main()
@@ -0,0 +1,409 @@
"""CPU-only synthetic tests: no Torch/Brian import, GPU, remote, or brain run."""
import copy
import hashlib
import importlib.util
import json
from pathlib import Path
import sys
import tempfile
import types
import unittest
from unittest import mock
import numpy as np
import runtime_bridge as bridge
HERE = Path(__file__).absolute().parent
AJ = HERE.parent / 'apl-timing-lab-v1'
def write_json(path, data):
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(data), encoding='utf-8')
def spec(root, name='cal-physiological-00-s51101'):
return dict(name=name, kind='calibration', steps=1000, dt_ms=.1, duration_ms=100.,
model={'fixed': True}, graph_dir=str(root / 'graph'), apl_bundle_dir=str(root / 'bundle'),
coefficients_path=str(root / 'coefficients.json'), science_python=str(root / 'venv/python'),
legacy_apl_worker=str(root / 'legacy_apl_worker.py'),
apl={'tau_ms': 20., 'gain': .01, 'normalization': 1.}, apl_delay_steps=18,
record_history=False, training=False, precision='float64', apl_precision='float32',
budget_root=str(root / 'old-exp'), output_budget_bytes=1024)
def inventory(root):
cfg = dict(control_cases=['control-phys', 'control-matched'], validation={
'cohorts': list(bridge.COHORTS), 'seeds': [101, 102, 103, 104, 105],
'modes': ['physiological', 'matched_energy'], 'odor_count': 6,
'repeat_first_seed_each_odor': True})
controls = [dict(name=name, source_case=str(root / 'old-cases' / name),
source_output=str(root / 'old-gpu' / name)) for name in cfg['control_cases']]
rows = [dict(cohort=cohort, mode=mode, odor_index=oi, seed=seed,
name=f'{cohort}-{mode}-{oi:02d}-s{seed}') for cohort in bridge.COHORTS
for mode in cfg['validation']['modes'] for oi in range(6) for seed in cfg['validation']['seeds']]
write_json(root / 'protocol/control-cases.json', controls)
write_json(root / 'protocol/validation-cases.json', rows)
return cfg, rows
def gate(root, stage, **values):
write_json(root / 'audit' / (stage + '-gate.json'), dict(stage=stage, pass_all=True, **values))
def seed_summary(root, cfg, rows):
base = bridge.cohort_rows(rows, cfg, 'seed_validation')
repeated = [row for row in base if row['seed'] == cfg['validation']['seeds'][0]]
pairs = [(row['name'], 0) for row in base] + [(row['name'], 1) for row in repeated]
return dict(phase='4AK', cohort='seed_validation', apl_delay_steps=18, duration_ms=100.,
seeds=cfg['validation']['seeds'], pass_all=True, execution_gate_pass=True,
representation_gate_pass=True, numerical_integrity_pass=True, exact_repeat_pass=True,
expected_base_trials=60, valid_base_trials=60, expected_repeats=12, checked_repeats=12,
checked_timing_trials=72, runs=[dict(case=row['name'], cohort='seed_validation',
validation_cohort='seed_validation') for row in base],
repeats=[dict(case=row['name'], pass_all=True) for row in repeated],
timing_checks=[dict(case=name, repeat=repeat, pass_all=True, apl_delay_steps=18, steps=1000)
for name, repeat in pairs], input_output_provenance=[dict(case=name, repeat=repeat) for name, repeat in pairs],
modes={mode: dict(gate=True) for mode in cfg['validation']['modes']},
prerequisite_input_sha256={'validation_inventory': bridge.digest(root / 'protocol/validation-cases.json')})
def bind_seed_gate(root, summary):
path = root / 'validation/seed_validation/summary.json'
write_json(path, summary)
gate(root, 'seed-validation', cohort='seed_validation', execution_gate_pass=True,
representation_gate_pass=True, summary='validation/seed_validation/summary.json',
summary_sha256=bridge.digest(path), validation_inventory_sha256=bridge.digest(root / 'protocol/validation-cases.json'))
class LoaderTests(unittest.TestCase):
def test_verified_import_preserves_file_and_globals_without_pyc(self):
with tempfile.TemporaryDirectory() as temporary:
path = Path(temporary) / 'sealed.py'
data = b'VALUE = 37\n'
path.write_bytes(data)
name = '_test_phase4ak_sealed'
try:
module = bridge.load_checked(name, path, hashlib.sha256(data).hexdigest())
self.assertEqual(module.VALUE, 37)
self.assertEqual(Path(module.__file__), path)
self.assertIs(bridge.load_checked(name, path, hashlib.sha256(data).hexdigest()), module)
self.assertNotIn('__phase4ak_loaded_sha256__', module.__dict__)
self.assertFalse((path.parent / '__pycache__').exists())
finally:
sys.modules.pop(name, None); bridge._LOADED.pop(name, None)
def test_sha_checked_before_execution(self):
with tempfile.TemporaryDirectory() as temporary:
path = Path(temporary) / 'sealed.py'
path.write_text('raise RuntimeError("must not execute")', encoding='utf-8')
with self.assertRaisesRegex(ValueError, 'SHA mismatch'):
bridge.load_checked('_test_bad_pin', path, '0' * 64)
self.assertNotIn('_test_bad_pin', sys.modules)
def test_existing_name_collision_is_not_silently_replaced(self):
with tempfile.TemporaryDirectory() as temporary:
path = Path(temporary) / 'sealed.py'
path.write_text('VALUE = 1', encoding='utf-8')
old = types.ModuleType('_test_collision')
sys.modules[old.__name__] = old
try:
with self.assertRaisesRegex(ValueError, 'unverified module'):
bridge.load_checked(old.__name__, path, bridge.digest(path))
self.assertIs(sys.modules[old.__name__], old)
finally:
sys.modules.pop(old.__name__, None)
def test_real_pure_sealed_module_load_does_not_import_torch_or_brian(self):
self.assertNotIn('torch', sys.modules)
self.assertNotIn('brian2', sys.modules)
compare = bridge.sealed('compare_timing.py', AJ)
self.assertEqual(bridge.digest(compare.__file__), bridge.AJ_PINS['compare_timing.py'])
self.assertTrue(callable(compare.compare))
self.assertNotIn('torch', sys.modules)
self.assertNotIn('brian2', sys.modules)
class InputTests(unittest.TestCase):
def setUp(self):
self.temporary = tempfile.TemporaryDirectory()
self.root = Path(self.temporary.name)
self.old, self.new = self.root / 'old', self.root / 'new'
self.old.mkdir(); self.new.mkdir()
self.old_spec = spec(self.root)
self.new_spec = dict(self.old_spec, budget_root=str(self.root / 'new-exp'), output_budget_bytes=2048)
write_json(self.old / 'spec.json', self.old_spec)
write_json(self.new / 'spec.json', self.new_spec)
for name in ('requests.npz', 'pn-drive.npz'):
for directory in (self.old, self.new):
(directory / name).write_bytes(b'identical synthetic saved input bytes')
def tearDown(self):
self.temporary.cleanup()
def test_control_allows_only_budget_difference(self):
fresh, old, evidence = bridge.control_inputs(self.new, self.old)
self.assertEqual(fresh['apl_delay_steps'], old['apl_delay_steps'])
self.assertEqual(len(evidence), 6)
changed = dict(self.new_spec, mode='changed')
write_json(self.new / 'spec.json', changed)
with self.assertRaisesRegex(ValueError, 'beyond the two budget fields'):
bridge.control_inputs(self.new, self.old)
def test_drive_and_request_bytes_both_checked(self):
for name in ('requests.npz', 'pn-drive.npz'):
with self.subTest(name=name):
original = (self.new / name).read_bytes()
(self.new / name).write_bytes(original + b'changed')
with self.assertRaisesRegex(ValueError, name):
bridge.control_inputs(self.new, self.old)
(self.new / name).write_bytes(original)
def test_real_d18_required_no_fake_d0(self):
for value in (0, True, 18.0):
with self.subTest(value=value):
write_json(self.new / 'spec.json', dict(self.new_spec, apl_delay_steps=value))
with self.assertRaisesRegex(ValueError, 'D18'):
bridge.control_inputs(self.new, self.old)
def test_initial_state_presence_and_bytes_checked(self):
(self.new / 'arrays.npz').write_bytes(b'a')
with self.assertRaisesRegex(ValueError, 'presence'):
bridge.control_inputs(self.new, self.old)
(self.old / 'arrays.npz').write_bytes(b'b')
with self.assertRaisesRegex(ValueError, 'arrays.npz'):
bridge.control_inputs(self.new, self.old)
def test_exclusive_output_and_new_budget_containment(self):
root = Path(self.new_spec['budget_root'])
root.mkdir()
out = root / 'gpu' / 'run'
bridge._new_output(self.new, out)
out.mkdir(parents=True)
with self.assertRaisesRegex(ValueError, 'exclusive'):
bridge._new_output(self.new, out)
with self.assertRaisesRegex(ValueError, 'exclusive'):
bridge._new_output(self.new, self.root / 'elsewhere')
def test_control_refuses_overwrite_before_reading_outputs(self):
report = self.root / 'report.json'
report.write_text('keep me', encoding='utf-8')
with self.assertRaisesRegex(ValueError, 'existing control'):
bridge.control_identity('missing-new', 'missing-old', self.new, self.old, report)
self.assertEqual(report.read_text(encoding='utf-8'), 'keep me')
class GateTests(unittest.TestCase):
def setUp(self):
self.temporary = tempfile.TemporaryDirectory()
self.root = Path(self.temporary.name)
self.cfg, self.rows = inventory(self.root)
def tearDown(self):
self.temporary.cleanup()
def test_exact_120_cells_and_fixed_two_probes(self):
controls, rows = bridge.inventories(self.root, self.cfg)
self.assertEqual(len(controls), 2)
for cohort in bridge.COHORTS:
probes = bridge.probe_rows(rows, self.cfg, cohort)
self.assertEqual(len(probes), 2)
self.assertTrue(all(row['odor_index'] == 0 and row['seed'] == 101 for row in probes))
def test_duplicate_or_replaced_cell_rejected(self):
rows = copy.deepcopy(self.rows)
rows[-1] = rows[0]
write_json(self.root / 'protocol/validation-cases.json', rows)
with self.assertRaises(ValueError):
bridge.inventories(self.root, self.cfg)
def test_controls_do_not_run_brian_or_repeats(self):
name = self.cfg['control_cases'][0]
bridge.authorize_case(self.root, self.cfg, 'controls', name, 'gpu', 0)
for backend, repeat in (('oracle', 0), ('gpu', 1)):
with self.assertRaises(ValueError):
bridge.authorize_case(self.root, self.cfg, 'controls', name, backend, repeat)
def test_probes_before_other_seed_runs(self):
gate(self.root, 'controls')
probe = bridge.probe_rows(self.rows, self.cfg, 'seed_validation')[0]
bridge.authorize_case(self.root, self.cfg, 'seed_validation', probe['name'], 'oracle', 0)
later = next(row for row in self.rows if row['cohort'] == 'seed_validation' and row['seed'] == 102)
with self.assertRaises(FileNotFoundError):
bridge.authorize_case(self.root, self.cfg, 'seed_validation', later['name'], 'gpu', 0)
gate(self.root, 'seed-probes')
bridge.authorize_case(self.root, self.cfg, 'seed_validation', later['name'], 'gpu', 0)
with self.assertRaises(ValueError):
bridge.authorize_case(self.root, self.cfg, 'seed_validation', later['name'], 'oracle', 0)
with self.assertRaises(ValueError):
bridge.authorize_case(self.root, self.cfg, 'seed_validation', later['name'], 'gpu', 1)
def test_novel_denied_on_representation_failure_even_execution_passes(self):
gate(self.root, 'controls')
gate(self.root, 'seed-validation', execution_gate_pass=True, representation_gate_pass=False)
probe = bridge.probe_rows(self.rows, self.cfg, 'novel_to_aj')[0]
with self.assertRaisesRegex(ValueError, 'representation'):
bridge.authorize_case(self.root, self.cfg, 'novel_to_aj', probe['name'], 'gpu', 0)
def test_novel_requires_both_gate_and_underlying_summary(self):
gate(self.root, 'controls')
probe = bridge.probe_rows(self.rows, self.cfg, 'novel_to_aj')[0]
summary = seed_summary(self.root, self.cfg, self.rows)
summary['representation_gate_pass'] = False
bind_seed_gate(self.root, summary)
with self.assertRaisesRegex(ValueError, 'summary'):
bridge.authorize_case(self.root, self.cfg, 'novel_to_aj', probe['name'], 'gpu', 0)
summary['representation_gate_pass'] = True
bind_seed_gate(self.root, summary)
bridge.authorize_case(self.root, self.cfg, 'novel_to_aj', probe['name'], 'gpu', 0)
def test_novel_rejects_summary_hash_or_cohort_misbinding(self):
gate(self.root, 'controls')
summary = seed_summary(self.root, self.cfg, self.rows)
bind_seed_gate(self.root, summary)
probe = bridge.probe_rows(self.rows, self.cfg, 'novel_to_aj')[0]
summary['cohort'] = 'novel_to_aj'
write_json(self.root / 'validation/seed_validation/summary.json', summary)
with self.assertRaisesRegex(ValueError, 'exact summary'):
bridge.authorize_case(self.root, self.cfg, 'novel_to_aj', probe['name'], 'gpu', 0)
bind_seed_gate(self.root, summary)
with self.assertRaisesRegex(ValueError, 'identity'):
bridge.authorize_case(self.root, self.cfg, 'novel_to_aj', probe['name'], 'gpu', 0)
def test_novel_rejects_replaced_case_repeat_or_timing_even_with_correct_counts(self):
gate(self.root, 'controls')
probe = bridge.probe_rows(self.rows, self.cfg, 'novel_to_aj')[0]
for key in ('runs', 'repeats', 'timing_checks', 'input_output_provenance'):
with self.subTest(key=key):
summary = seed_summary(self.root, self.cfg, self.rows)
summary[key][0]['case'] = 'not-a-registered-case'
bind_seed_gate(self.root, summary)
with self.assertRaises(ValueError):
bridge.authorize_case(self.root, self.cfg, 'novel_to_aj', probe['name'], 'gpu', 0)
def test_any_stop_marker_prevents_all_scientific_actions(self):
for kind in ('representation_failure', 'execution_or_numerical_failure'):
with self.subTest(kind=kind):
write_json(self.root / 'audit/stopped-seed-validation.json', {'stop_kind': kind})
for backend in ('gpu', 'oracle', 'component'):
with self.assertRaisesRegex(ValueError, 'stop marker'):
bridge.authorize_case(self.root, self.cfg, 'controls', self.cfg['control_cases'][0], backend, 0)
def test_standalone_action_failure_persists_stop_and_never_retries(self):
action = mock.Mock(side_effect=RuntimeError('synthetic failure; no science executed'))
with self.assertRaisesRegex(RuntimeError, 'synthetic failure'):
bridge.guarded_action(self.root, 'gpu', 'controls', 'control-phys', 0, action)
marker = self.root / 'audit/stopped-case-gpu-controls-control-phys-r0.json'
report = bridge.read(marker)
self.assertEqual(report['stop_kind'], 'execution_or_numerical_failure')
self.assertFalse(report['numerical_instability_inferred_from_execution_error'])
before = marker.read_bytes()
with self.assertRaisesRegex(ValueError, 'stop marker'):
bridge.guarded_action(self.root, 'gpu', 'controls', 'control-phys', 0, action)
self.assertEqual(action.call_count, 1)
self.assertEqual(marker.read_bytes(), before)
def test_successful_guarded_action_adds_no_stop(self):
expected = {'pass_all': True}
self.assertIs(bridge.guarded_action(self.root, 'gpu', 'controls', 'control-phys', 0, lambda: expected), expected)
bridge.ensure_unstopped(self.root)
class InvocationTests(unittest.TestCase):
def test_original_gpu_function_receives_new_paths_unchanged(self):
with tempfile.TemporaryDirectory() as temporary:
root = Path(temporary)
case, output, build = root / 'case', root / 'new-exp/gpu/run', root / 'new-exp/build'
data = spec(root)
data['budget_root'] = str(root / 'new-exp')
write_json(case / 'spec.json', data)
runtime = types.SimpleNamespace(run_gpu=mock.Mock(return_value={'pass_all': True}))
with mock.patch.object(bridge, 'sealed', return_value=runtime), mock.patch.object(bridge, '_receipt'):
result = bridge.run_gpu(case, output, build)
self.assertTrue(result['pass_all'])
runtime.run_gpu.assert_called_once_with(case, output, build)
def test_original_oracle_function_is_not_given_candidate_trace(self):
with tempfile.TemporaryDirectory() as temporary:
root = Path(temporary)
case, output = root / 'case', root / 'new-exp/oracle/run'
data = spec(root); data['budget_root'] = str(root / 'new-exp')
write_json(case / 'spec.json', data)
runtime = types.SimpleNamespace(run_case=mock.Mock(return_value={'pass_all': True}))
with mock.patch.object(bridge, 'sealed', return_value=runtime), mock.patch.object(bridge, '_receipt'):
bridge.run_oracle(case, output)
runtime.run_case.assert_called_once_with(case, output)
class ControlEvidenceTests(unittest.TestCase):
def test_real_sealed_comparator_accepts_complete_synthetic_d18_and_rejects_signed_zero_tail(self):
# Artifact construction only: these zero traces were not produced by any model.
aj = bridge.sealed('compare_timing.py', AJ)
timing = bridge.sealed('timing_queue.py', AJ)
with tempfile.TemporaryDirectory() as temporary:
root = Path(temporary)
cases, outputs = [root / name for name in ('old-case', 'new-case')], [root / name for name in ('old-out', 'new-out')]
base = spec(root)
(root / 'graph').mkdir()
np.save(root / 'graph/weights.npy', np.zeros(1, np.float64), allow_pickle=False)
write_json(root / 'coefficients.json', {'synthetic_only': True})
states = dict(v=np.zeros(166700, np.float64), g=np.zeros(166700, np.float64),
ref=np.zeros(166700, np.int32), counts=np.zeros(166700, np.int32),
step=np.empty(0, np.int32), neuron_idx=np.empty(0, np.int32))
generated = np.zeros((1000, 4064), np.float32)
pending = np.zeros((18, 4064), np.float32)
audit = timing.audit_sequence(generated, generated, pending, 18)
audit.update(generated_rows=1000, applied_generated_rows=982, pending_shape=[18, 4064],
pending_application_tick_start=1000, pending_application_tick_stop_exclusive=1018,
pending_generated_tick_start=982, pending_generated_tick_stop_exclusive=1000,
pending_raw_sha256=aj.raw_hash(pending), final_apl_state_float32=[0., 0.],
final_apl_state_u32_bits=[0, 0], final_apl_state_nonzero=False,
finite_generated_sequence_only=True, future_apl_decay_or_feedback_generated=False,
closed_loop_branch_integrals_claimed_equal=False, biological_delay_measurement_claimed=False)
hashes = [{**{name + '_sha256': aj.raw_hash(states[name]) for name in ('v', 'g', 'ref')}, 'tick': tick}
for tick in range(1000)]
queues = [aj._queue_digest(tick, np.empty(0, np.int64), np.empty(0, np.uint8)) for tick in range(1000)]
for index, (case, output) in enumerate(zip(cases, outputs)):
data = dict(base, budget_root=str(root / ('budget-' + str(index))), output_budget_bytes=10000 + index)
write_json(case / 'spec.json', data)
for name in ('requests.npz', 'pn-drive.npz'):
(case / name).write_bytes(b'synthetic-identical-input')
output.mkdir()
np.savez_compressed(output / 'state.npz', **states)
for name, value in (('drive', np.zeros((1000, 2), np.float32)), ('state', np.zeros((1000, 2), np.float32)),
('inhibition', generated), ('applied', generated), ('pending-tail', pending)):
np.save(output / ('apl-' + name + '.float32.npy'), value, allow_pickle=False)
for name, rows in (('tick-state-hashes.jsonl', hashes), ('queue.jsonl', queues)):
(output / name).write_text(''.join(json.dumps(row) + '\n' for row in rows), encoding='utf-8')
(output / 'requests.csv').write_text('tick,neuron_idx,attempted,accepted,rejected\n', encoding='utf-8')
component = {'synthetic_fixture': True}
write_json(output / 'apl-component.json', component)
write_json(output / 'apl-timing-audit.json', audit)
inputs = {name: bridge.digest(case / name) for name in ('spec.json', 'requests.npz')}
inputs.update({'base_weights.npy': bridge.digest(root / 'graph/weights.npy'),
'coefficients.json': bridge.digest(root / 'coefficients.json')})
summary = dict(case=base['name'], complete=True, pass_all=True, steps=1000, completed_ticks=1000,
nodes=166700, edges=25582938, precision='float64', apl_precision='float32', state_units='SI volts',
total_spikes=0, requested=0, accepted_requests=0, rejected_requests=0, arriving_edges=0,
accepted_arriving_edges=0, counts_match_sparse_events=True, all_finite=True, record_history=False,
apl_fast_edges_zeroed=5845, kc_targets_present=4064, effective_weights_raw_sha256='0' * 64,
apl_schedule='same synthetic schedule', apl_si_conversion='same synthetic conversion',
sealed_ae_backend_sha256='1' * 64, learning=False, apl_delay_steps=18, apl_timing=audit,
source_provenance={'same_sealed_source': True}, pending_generated_count=18,
pending_initial_zero_prefix=0, pending_tail_shape=[18, 4064], future_generated_decay_tail_included=False,
apl_component=component, input_sha256=inputs, build={'path': str(root / ('build-' + str(index)))})
write_json(output / 'summary.json', summary)
result = bridge.control_identity(outputs[1], outputs[0], cases[1], cases[0], aj_model=AJ)
self.assertTrue(result['pass_all'], result.get('error', result['failed_checks']))
pending[0, 0] = np.float32(-0.)
np.save(outputs[1] / 'apl-pending-tail.float32.npy', pending, allow_pickle=False)
failed = bridge.control_identity(outputs[1], outputs[0], cases[1], cases[0], aj_model=AJ)
self.assertFalse(failed['pass_all'])
self.assertIn('apl.pending.bitwise_exact', failed['failed_checks'])
self.assertIn('fresh_gpu.fixed_delay_pending.bitwise_exact', failed['failed_checks'])
if __name__ == '__main__':
unittest.main()
@@ -0,0 +1,298 @@
"""Synthetic-only validation tests: no historical outputs or brain execution."""
import copy
import json
from pathlib import Path
import tempfile
import types
import unittest
from unittest.mock import patch
import numpy as np
import pandas as pd
import validation as val
HERE = Path(__file__).resolve().parent
LEGACY = val.load_frozen(HERE.parent / "author-apl-lab-v2/calibration.py", val.AG_SHA256, "ak_test_ag")
TIMING = val.load_frozen(HERE.parent / "apl-timing-lab-v1/calibration.py", val.AJ_SHA256, "ak_test_aj")
def config():
cfg = val.read(HERE / "config.json")
cfg["validation"]["seeds"] = [1001, 1002, 1003, 1004, 1005] # Synthetic, not proposed scientific seeds.
return cfg
def panel():
return [dict(odor_id=oid, odor_name=oid, split="calibration" if i < 6 else "heldout",
mapped_response_sum=val.MEDIAN)
for i, oid in enumerate(sorted(LEGACY.ORIGINAL_CAL_IDS) + ["synthetic-new-" + str(i) for i in range(6)])]
def records(cfg):
rows = []
pp = panel()
for ci, cohort in enumerate(val.COHORTS):
for mode in val.MODES:
for oi in range(6):
for seed in cfg["validation"]["seeds"]:
rows.append(dict(name=f"test-{mode}-{oi}-{seed}", cohort=cohort,
source_panel_split=val.SPLITS[cohort], mode=mode, odor_id=pp[6 * ci + oi]["odor_id"],
odor_index=oi, seed=seed, targets=1, requests=0))
return rows
def encoder(cfg, inventory):
return dict(panel_count=12, cal_count=6, novel_to_aj_count=6, median_mapped_response_sum=val.MEDIAN,
seeds=cfg["validation"]["seeds"], seeds_static_audit_sha256="a" * 64,
cohorts_static_panel_rows={cohort: [dict(odor_id=oid, odor_index=i, source_panel_split=val.SPLITS[cohort])
for i, oid in enumerate(inventory[cohort]["odor_ids"])] for cohort in val.COHORTS},
requested_before_any_dynamics=True, historical_never_simulated_claim=False)
def save(path, value):
path.parent.mkdir(parents=True, exist_ok=True)
with path.open("x", encoding="utf-8") as stream:
json.dump(value, stream, allow_nan=False)
def make_raw_trial(root):
"""Tiny neuron state with the real full-width APL trace schema."""
output, case, bundle = root / "out", root / "case", root / "bundle"
output.mkdir(); case.mkdir(); bundle.mkdir()
steps, neurons = 20, 2
cfg = dict(neurons=neurons, edges=0)
for filename in ("input_matrix.npy", "output_matrix.npy", "kc_globals.npy", "apl_globals.npy"):
np.save(bundle / filename, np.zeros(1, np.int32))
spec = dict(name="synthetic", steps=steps, validation_cohort="novel_to_aj", source_panel_split="heldout",
apl_delay_steps=18, mode="physiological", odor_id="synthetic", odor_name="synthetic", seed=1001,
expected_external_events=1., rate_sum_hz=50., apl_bundle_dir=str(bundle))
save(case / "spec.json", spec)
np.savez(case / "requests.npz", tick=np.empty(0, np.int32), neuron_idx=np.empty(0, np.int32))
state = {"step": np.empty(0, np.int32), "neuron_idx": np.empty(0, np.int32),
"counts": np.zeros(neurons, np.int32), "v": np.zeros(neurons, np.float64),
"g": np.zeros(neurons, np.float64), "ref": np.zeros(neurons, np.int32)}
np.savez(output / "state.npz", **state)
hashes = [dict(tick=t, **{key + "_sha256": LEGACY.raw_hash(state[key]) for key in ("v", "g", "ref")}) for t in range(steps)]
queues = [dict(tick=t, count=0, accepted_count=0, ordered_edge_sha256="0" * 64,
accepted_mask_sha256="0" * 64, joint_sha256="0" * 64) for t in range(steps)]
for filename, rows in (("tick-state-hashes.jsonl", hashes), ("queue.jsonl", queues)):
(output / filename).write_text("".join(json.dumps(row) + "\n" for row in rows), encoding="utf-8")
(output / "requests.csv").write_text("tick,neuron_idx,attempted,accepted,rejected\n", encoding="utf-8")
for filename, width in LEGACY.APL_FILES.items():
np.save(output / filename, np.zeros((steps, width), np.float32))
np.save(output / "apl-applied.float32.npy", np.zeros((steps, 4064), np.float32))
pending = np.zeros((18, 4064), np.float32)
np.save(output / "apl-pending-tail.float32.npy", pending)
audit = dict(pass_all=True, apl_delay_steps=18, steps=steps, pending_generated_count=18,
pending_initial_zero_prefix=0, pending_application_tick_start=steps,
pending_application_tick_stop_exclusive=steps + 18, pending_generated_tick_start=steps - 18,
pending_generated_tick_stop_exclusive=steps, initial_padding_positive_zero=True,
sample_bits_preserved=True, brain_tail_advanced=False, generated_trace="apl-inhibition.float32.npy",
applied_trace="apl-applied.float32.npy", pending_trace="apl-pending-tail.float32.npy",
pending_raw_sha256=LEGACY.raw_hash(pending), pending_queue_drained=False,
finite_generated_sequence_only=True, future_apl_decay_or_feedback_generated=False,
closed_loop_branch_integrals_claimed_equal=False, biological_delay_measurement_claimed=False,
final_apl_state_float32=[0., 0.], final_apl_state_u32_bits=[0, 0], final_apl_state_nonzero=False)
save(output / "apl-timing-audit.json", audit)
component = dict(ok=True, n_neurons=neurons, n_kc=2, n_apl=2, dt_ms=.1,
files_sha256={name: val.digest(bundle / name) for name in
("input_matrix.npy", "output_matrix.npy", "kc_globals.npy", "apl_globals.npy")})
save(output / "apl-component.json", component)
save(output / "summary.json", dict(complete=True, pass_all=True, all_finite=True, steps=steps,
completed_ticks=steps, nodes=neurons, edges=0, precision="float64", apl_precision="float32",
case=spec["name"], record_history=False, learning=False, requested=0, accepted_requests=0,
rejected_requests=0, total_spikes=0, apl_component=component, apl_delay_steps=18, apl_timing=audit,
input_sha256={name: val.digest(case / name) for name in ("spec.json", "requests.npz")}))
return output, case, spec, cfg
def fake_trial(row, cohort, silent=False):
counts = np.zeros(1000, np.int32)
if not silent:
counts[row["odor_index"] * 50:row["odor_index"] * 50 + 50] = 1
return dict(kc_counts=counts, expected_external_events=1., external_events=1,
record=dict(case=row["name"], mode=row["mode"], seed=row["seed"], odor_id=row["odor_id"],
requested=row["requests"], split=cohort, cohort=cohort, source_panel_split=val.SPLITS[cohort]),
timing=dict(report=dict(pass_all=True)), apl={})
class ValidationTests(unittest.TestCase):
def test_source_pins_and_globals_are_unchanged(self):
self.assertEqual(LEGACY.ORIGINAL_SEEDS, (51101, 51102, 51103, 51104, 51105))
self.assertFalse(hasattr(LEGACY, "EXP"))
self.assertFalse(hasattr(TIMING, "EXP"))
with self.assertRaisesRegex(ValueError, "SHA"):
val.load_frozen(HERE.parent / "author-apl-lab-v2/calibration.py", "0" * 64, "bad_pin")
def test_inventory_accepts_configured_seeds_and_keeps_static_halves(self):
cfg = config(); inv = val.validate_inventory(records(cfg), cfg, panel(), LEGACY)
self.assertEqual([len(inv[c]["records"]) for c in val.COHORTS], [60, 60])
self.assertEqual(inv["novel_to_aj"]["odor_ids"], ["synthetic-new-" + str(i) for i in range(6)])
val.validate_encoder(encoder(cfg, inv), inv, cfg)
self.assertEqual(LEGACY.ORIGINAL_SEEDS[0], 51101)
def test_inventory_rejects_missing_duplicate_mislabelled_and_unaudited_cells(self):
cfg = config()
variants = []
rr = records(cfg); variants.append(rr[:-1])
rr = records(cfg); rr[-1] = copy.deepcopy(rr[-2]); variants.append(rr)
for field, value in (("source_panel_split", "heldout"), ("odor_id", "wrong"),
("seed", 51101), ("name", "../outside"), ("odor_index", True), ("targets", 0)):
rr = records(cfg); rr[0][field] = value; variants.append(rr)
for rr in variants:
with self.subTest(first=rr[0]), self.assertRaises(ValueError):
val.validate_inventory(rr, cfg, panel(), LEGACY)
def test_no_gate_relaxation_or_subset_median(self):
for key, value in (("minimum_separable_odor_pairs", 1), ("sparse_min_fraction", .01),
("repeat_exact_required", False)):
cfg = config(); cfg["gates"][key] = value
with self.subTest(key=key), self.assertRaises(ValueError):
val.validate_inventory(records(cfg), cfg, panel(), LEGACY)
pp = panel()
for row in pp:
row["mapped_response_sum"] = 1.
with self.assertRaisesRegex(ValueError, "median"):
val.validate_inventory(records(config()), config(), pp, LEGACY)
def test_encoder_rejects_history_claim_or_changed_panel_rows(self):
cfg = config(); inv = val.validate_inventory(records(cfg), cfg, panel(), LEGACY)
for key, value in (("historical_never_simulated_claim", True), ("requested_before_any_dynamics", False),
("seeds_static_audit_sha256", ""), ("cohorts_static_panel_rows", {})):
ee = encoder(cfg, inv); ee[key] = value
with self.subTest(key=key), self.assertRaises(ValueError):
val.validate_encoder(ee, inv, cfg)
def test_encoder_actual_prepare_panel_row_extension(self):
cfg = config(); inv = val.validate_inventory(records(cfg), cfg, panel(), LEGACY)
ee = encoder(cfg, inv)
for ci, cohort in enumerate(val.COHORTS):
for oi, row in enumerate(ee["cohorts_static_panel_rows"][cohort]):
row["source_panel_row"] = ci * 6 + oi
val.validate_encoder(ee, inv, cfg)
ee["cohorts_static_panel_rows"]["novel_to_aj"][0]["source_panel_row"] = 0
with self.assertRaisesRegex(ValueError, "panel row"):
val.validate_encoder(ee, inv, cfg)
def test_fullgraph_case_matches_static_physics_and_exact_input_expectation(self):
cfg = config(); row = records(cfg)[60]
row.update(source_panel_row=6, expected_external_events=10., rates_sum=100.)
spec = dict(name=row["name"], kind="fullgraph", validation_cohort=row["cohort"],
source_panel_split=row["source_panel_split"], source_panel_row=6,
**{key: row[key] for key in ("mode", "odor_id", "odor_index", "seed")},
apl_delay_steps=18, steps=1000, dt_ms=.1, duration_ms=100., training=False, record_history=False,
model={"resting_potential_mv": -52.}, graph_dir="unchanged-graph", apl_bundle_dir="unchanged-bundle",
apl={"gain": .01}, coefficients_path="unchanged-coefficients", science_python="unchanged-entry",
legacy_apl_worker="unchanged-worker", precision="float64", apl_precision="float32",
target_count=1, rate_sum_hz=100., expected_external_events=10.)
with tempfile.TemporaryDirectory() as tmp:
case = Path(tmp)
save(case / "spec.json", spec)
np.savez(case / "pn-drive.npz", targets=np.array([10], np.int32), rates_hz=np.array([100.], np.float32))
np.savez(case / "requests.npz", tick=np.empty(0, np.int32), neuron_idx=np.empty(0, np.int32))
self.assertEqual(val.validate_case(case, row, cfg, spec), spec)
wrong = copy.deepcopy(spec); wrong["model"]["resting_potential_mv"] = -51.
with self.assertRaisesRegex(ValueError, "physical field"):
val.validate_case(case, row, cfg, wrong)
wrong_row = dict(row, targets=2)
with self.assertRaisesRegex(ValueError, "PN drive"):
val.validate_case(case, wrong_row, cfg, spec)
def test_real_legacy_reader_record_is_relabelled_without_globals_or_numerical_changes(self):
with tempfile.TemporaryDirectory() as tmp:
output, case, spec, cfg = make_raw_trial(Path(tmp))
trial = val.read_validation_trial(LEGACY, TIMING, output, case, spec, np.arange(2, dtype=np.int32), cfg)
try:
self.assertEqual(trial["record"]["split"], "novel_to_aj")
self.assertEqual(trial["record"]["source_panel_split"], "heldout")
self.assertFalse(trial["record"]["historical_never_simulated_claim"])
self.assertTrue(trial["timing"]["report"]["pass_all"])
self.assertEqual(LEGACY.ORIGINAL_SEEDS[0], 51101)
finally:
val.close_trial(trial)
def test_real_reader_still_rejects_missing_state_and_delay_zero(self):
with tempfile.TemporaryDirectory() as tmp:
output, case, spec, cfg = make_raw_trial(Path(tmp))
bad = dict(spec, apl_delay_steps=0)
with self.assertRaisesRegex(ValueError, "delay"):
val.read_validation_trial(LEGACY, TIMING, output, case, bad, np.arange(2, dtype=np.int32), cfg)
(output / "state.npz").unlink()
with self.assertRaises(FileNotFoundError):
val.read_validation_trial(LEGACY, TIMING, output, case, spec, np.arange(2, dtype=np.int32), cfg)
def collect(self, silent=False, broken_repeat=False, missing=False):
cfg = config(); inv = val.validate_inventory(records(cfg), cfg, panel(), LEGACY)
cohort = "seed_validation"; rows = inv[cohort]["records"]
byname = {row["name"]: row for row in rows}
accessed = []
def load(legacy, timing, output, case, spec, kc, config_arg):
accessed.append(str(output))
if missing and spec["name"] == rows[0]["name"]:
raise FileNotFoundError("synthetic missing evidence")
return fake_trial(byname[spec["name"]], cohort, silent)
timing = types.SimpleNamespace(timing_repeat=lambda *args: dict(pass_all=not broken_repeat,
checks=dict(apl_applied=not broken_repeat)))
with patch.object(val, "validate_case", side_effect=lambda case, row, *args: row), \
patch.object(val, "read_validation_trial", side_effect=load), \
patch.object(val, "evidence_hashes", return_value={"synthetic": True}):
result = val.collect_cohort(cohort, rows, inv[cohort]["odor_ids"], cfg, Path("synthetic"),
np.arange(2, dtype=np.int32), {}, LEGACY, timing)
return result, accessed
def test_full_60_plus_12_and_pair_specific_gate_without_other_cohort_read(self):
result, accessed = self.collect()
self.assertTrue(result["pass_all"])
self.assertEqual((result["valid_base_trials"], result["checked_repeats"], result["checked_timing_trials"]), (60, 12, 72))
self.assertEqual(len(accessed), 72)
self.assertFalse(any("novel_to_aj" in path for path in accessed))
for report in result["modes"].values():
self.assertEqual((report["pair_count"], report["within_distance_count"], report["between_distance_count"]), (15, 60, 75))
json.dumps(result, allow_nan=False)
def test_representation_failure_keeps_all_runs_and_is_not_execution_failure(self):
result, accessed = self.collect(silent=True)
self.assertTrue(result["execution_gate_pass"])
self.assertFalse(result["representation_gate_pass"])
self.assertFalse(result["pass_all"])
self.assertEqual(len(accessed), 72)
self.assertTrue(all(row["stage"] == "representation_gate" for row in result["failures"]))
def test_missing_evidence_and_repeat_failure_never_pass_execution(self):
for options in (dict(missing=True), dict(broken_repeat=True)):
with self.subTest(options=options):
result, _ = self.collect(**options)
self.assertFalse(result["execution_gate_pass"])
self.assertFalse(result["pass_all"])
self.assertTrue(result["failures"])
def test_none_recompute_is_deterministic_and_writes_nothing(self):
cfg = config(); rr = records(cfg); inv = val.validate_inventory(rr, cfg, panel(), LEGACY)
ee = encoder(cfg, inv)
ctx = types.SimpleNamespace(ROOT=Path("synthetic-root"), MODEL=Path("synthetic-model"), EXP=Path("synthetic-exp"),
AG_MODEL=Path("ag-model"), AJ_MODEL=Path("aj-model"), AG=Path("ag"), AJ=Path("aj"), CFG=cfg,
check=lambda: {}, save=lambda *args: self.fail("Read-only summarize wrote output"))
collected, _ = self.collect()
def read_fixture(path):
if path.name == "validation-cases.json": return rr
if path.name == "encoder-audit.json": return ee
if path.name == "spec.json": return dict(apl_delay_steps=18, training=False)
raise AssertionError("Unexpected input read: " + str(path))
def hash_fixture(path):
return val.PANEL_SHA256 if path.name == "frozen-odor-panel.parquet" else "a" * 64
with patch.dict("sys.modules", context=ctx), patch.object(val, "read", side_effect=read_fixture), \
patch.object(val, "digest", side_effect=hash_fixture), \
patch.object(val, "load_frozen", side_effect=[LEGACY, TIMING, LEGACY, TIMING]), \
patch.object(pd, "read_parquet", return_value=pd.DataFrame(panel())), \
patch.object(np, "load", return_value=np.arange(4064, dtype=np.int32)), \
patch.object(val, "collect_cohort", side_effect=lambda *args: copy.deepcopy(collected)):
first = val.summarize("seed_validation", None)
second = val.summarize("seed_validation", None)
self.assertEqual(first, second)
self.assertTrue(first["pass_all"])
json.dumps(first, allow_nan=False)
if __name__ == "__main__":
unittest.main()
@@ -0,0 +1,344 @@
"""Frozen-D18 validation cohorts; no simulation, fitting, or old heldout read.
Only the requested cohort's new trajectories are opened. The suite owns the
seed-validation -> novel-to-AJ unlock. Legacy modules are source-hash pinned,
loaded without writing bytecode, and never have their globals rebound.
"""
from __future__ import annotations
import hashlib
import json
from pathlib import Path
import re
import sys
import types
import numpy as np
AG_SHA256 = "edb9cb2d890471fd07afd88c959ef3540b0cd40af490fac3f26396b5e7f5bf9c"
AJ_SHA256 = "fb15ddeaa108305c8de697bbae36b23ab0414a7c58db51c66dce9feb4a048a0d"
PANEL_SHA256 = "907f16a56e024a8e2112b5751e53b0e6037b329fa110098af3d31b119c10a1a0"
COHORTS = ("seed_validation", "novel_to_aj")
SPLITS = dict(zip(COHORTS, ("calibration", "heldout")))
MODES = ("physiological", "matched_energy")
MEDIAN = 2.556107997894287
_DEFAULT_OUTPUT = object()
def require(ok, message):
if not ok:
raise ValueError(message)
def read(path):
return json.loads(Path(path).read_text(encoding="utf-8"))
def digest(path):
h = hashlib.sha256()
with Path(path).open("rb") as stream:
for block in iter(lambda: stream.read(8 << 20), b""):
h.update(block)
return h.hexdigest()
def load_frozen(path, expected, name):
path = Path(path)
source = path.read_bytes()
require(hashlib.sha256(source).hexdigest() == expected, "Frozen source SHA mismatch: " + str(path))
module = types.ModuleType(name)
module.__file__ = str(path)
sys.modules[name] = module
exec(compile(source, str(path), "exec"), module.__dict__)
return module
def validate_design(cfg):
design = cfg["validation"]
seeds = design["seeds"]
require(isinstance(seeds, list) and len(seeds) == 5 and len(set(seeds)) == 5 and
all(type(seed) is int and 0 <= seed < 2**63 for seed in seeds), "Need five explicitly audited seed integers")
require(design["cohorts"] == list(COHORTS) and design["modes"] == list(MODES) and
design["odor_count"] == 6 and design["duration_ms"] == 100.0 and
design["repeat_first_seed_each_odor"] is True, "Validation design changed")
require(type(cfg["apl_delay_steps"]) is int and cfg["apl_delay_steps"] == 18 and
cfg["neurons"] == 166700 and cfg["edges"] == 25582938 and cfg["training"] is False,
"Frozen D18/fullgraph/nonlearning scope changed")
gates = cfg["gates"]
require(gates["sparse_min_fraction"] == .03 and gates["sparse_max_fraction"] == .09 and
gates["max_fraction_strict"] == .5 and gates["min_fraction_strict"] == 0 and
gates["minimum_separable_odor_pairs"] == 3 and all(gates[key] is True for key in
("same_jaccard_gt_between", "between_euclidean_gt_within", "both_modes_required",
"finite_required", "repeat_exact_required")), "Original complete representation/integrity gates changed")
return seeds
def validate_inventory(records, cfg, panel_rows, legacy):
"""Static 120-row inventory, preserving original panel row order in each half."""
seeds = validate_design(cfg)
require(isinstance(records, list) and len(records) == 120, "Inventory must contain exactly 120 base cases")
require(len(panel_rows) == 12 and [row["split"] for row in panel_rows] == ["calibration"] * 6 + ["heldout"] * 6,
"Frozen static panel order/splits changed")
all_ids = [row["odor_id"] for row in panel_rows]
require(all(isinstance(oid, str) and oid for oid in all_ids) and len(set(all_ids)) == 12 and
set(all_ids[:6]) == legacy.ORIGINAL_CAL_IDS, "Frozen panel identities invalid")
require(float(np.median([row["mapped_response_sum"] for row in panel_rows])) == MEDIAN,
"Matched-energy reference must remain the original full-12 median")
result = {}
names, keys = set(), set()
for row in records:
require(row["cohort"] in COHORTS and row["mode"] in MODES, "Unknown cohort/mode")
require(type(row["odor_index"]) is int and 0 <= row["odor_index"] < 6 and
type(row["seed"]) is int and row["seed"] in seeds, "Invalid odor index/seed")
require(isinstance(row["name"], str) and re.fullmatch(r"[A-Za-z0-9_-]+", row["name"]), "Unsafe case name")
namekey = (row["cohort"], row["name"])
key = (row["cohort"], row["mode"], row["odor_index"], row["seed"])
require(namekey not in names and key not in keys, "Duplicate case name or experimental cell")
names.add(namekey); keys.add(key)
offset = 0 if row["cohort"] == "seed_validation" else 6
require(row["source_panel_split"] == SPLITS[row["cohort"]] and
row["odor_id"] == all_ids[offset + row["odor_index"]], "Cohort identity/order/source split mismatch")
if "source_panel_row" in row:
require(type(row["source_panel_row"]) is int and row["source_panel_row"] == offset + row["odor_index"],
"Inventory original panel row mismatch")
require(type(row["targets"]) is int and 0 < row["targets"] <= cfg["neurons"] and
type(row["requests"]) is int and row["requests"] >= 0, "Invalid inventory target/request counts")
expected = {(cohort, mode, oi, seed) for cohort in COHORTS for mode in MODES for oi in range(6) for seed in seeds}
require(keys == expected, "Inventory missing or replacing a predeclared cell")
for index, cohort in enumerate(COHORTS):
rows = [row for row in records if row["cohort"] == cohort]
rows.sort(key=lambda row: (MODES.index(row["mode"]), row["odor_index"], seeds.index(row["seed"])))
result[cohort] = {"records": rows, "odor_ids": all_ids[index * 6:(index + 1) * 6]}
return result
def validate_encoder(encoder, inventory, cfg):
require(encoder["panel_count"] == 12 and encoder["cal_count"] == 6 and encoder["novel_to_aj_count"] == 6 and
encoder["median_mapped_response_sum"] == MEDIAN and encoder["seeds"] == cfg["validation"]["seeds"] and
encoder["requested_before_any_dynamics"] is True and encoder["historical_never_simulated_claim"] is False,
"Frozen encoder/reference or validation scope changed")
require(isinstance(encoder["seeds_static_audit_sha256"], str) and
re.fullmatch(r"[0-9a-f]{64}", encoder["seeds_static_audit_sha256"]), "Missing seed audit SHA")
expected = {cohort: [dict(odor_id=oid, odor_index=index, source_panel_split=SPLITS[cohort])
for index, oid in enumerate(inventory[cohort]["odor_ids"])] for cohort in COHORTS}
actual = encoder["cohorts_static_panel_rows"]
require(set(actual) == set(COHORTS), "Encoder cohort set changed")
for ci, cohort in enumerate(COHORTS):
require(len(actual[cohort]) == 6, "Encoder cohort panel count changed")
for index, (row, wanted) in enumerate(zip(actual[cohort], expected[cohort])):
require(all(row.get(key) == value for key, value in wanted.items()),
"Encoder cohort panel rows differ from frozen identities")
if "source_panel_row" in row:
require(type(row["source_panel_row"]) is int and row["source_panel_row"] == ci * 6 + index,
"Encoder original panel row mismatch")
def validate_case(case, row, cfg, frozen_spec):
spec = read(case / "spec.json")
require(spec["name"] == row["name"] and spec["kind"] == "fullgraph" and
spec["validation_cohort"] == row["cohort"] and spec["source_panel_split"] == row["source_panel_split"] and
all(spec[key] == row[key] for key in ("mode", "odor_id", "odor_index", "seed")), "Spec differs from validation inventory")
require(type(spec["apl_delay_steps"]) is int and spec["apl_delay_steps"] == 18 and spec["steps"] == 1000 and
spec["dt_ms"] == .1 and spec["duration_ms"] == 100.0 and spec["training"] is False and
spec["record_history"] is False, "Fixed D18/window/nonlearning schema changed")
if "source_panel_row" in row or "source_panel_row" in spec:
expected_row = (0 if row["cohort"] == "seed_validation" else 6) + row["odor_index"]
require(type(spec.get("source_panel_row")) is int and spec["source_panel_row"] == expected_row and
row.get("source_panel_row", expected_row) == expected_row, "Spec original panel row mismatch")
for key in ("model", "graph_dir", "apl_bundle_dir", "apl", "coefficients_path", "science_python",
"legacy_apl_worker", "precision", "apl_precision", "dt_ms", "duration_ms", "steps"):
require(spec[key] == frozen_spec[key], "Frozen physical field changed: " + key)
with np.load(case / "pn-drive.npz", allow_pickle=False) as source:
require(set(source.files) == {"targets", "rates_hz"}, "PN drive schema changed")
targets, rates = source["targets"], source["rates_hz"]
require(targets.dtype == np.int32 and targets.ndim == 1 and len(targets) == row["targets"] and
len(np.unique(targets)) == len(targets) and np.all((targets >= 0) & (targets < cfg["neurons"])) and
rates.dtype == np.float32 and rates.shape == targets.shape and np.isfinite(rates).all() and np.all(rates > 0),
"Invalid PN drive identities/rates; no sorting or zero-channel insertion is allowed")
expected_events = float(rates.sum()) * spec["steps"] * .1 / 1000.
require(spec["target_count"] == row["targets"] and spec["rate_sum_hz"] == float(rates.sum()) and
spec["expected_external_events"] == expected_events and np.isfinite(expected_events) and expected_events > 0,
"PN rates/spec event expectation disagree")
if "expected_external_events" in row:
require(row["expected_external_events"] == expected_events, "Inventory expected events disagree")
if "rates_sum" in row:
require(row["rates_sum"] == float(rates.sum()), "Inventory rate sum disagrees")
with np.load(case / "requests.npz", allow_pickle=False) as source:
require(set(source.files) == {"tick", "neuron_idx"} and len(source["tick"]) == row["requests"] and
np.isin(source["neuron_idx"], targets).all(), "Request count/targets differ from prepared input")
return spec
def read_validation_trial(legacy, timing, output, case, spec, kc_globals, cfg):
"""Reuse all sealed checks; replace only the returned descriptive record."""
cohort = spec["validation_cohort"]
require(cohort in COHORTS and spec["source_panel_split"] == SPLITS[cohort] and
type(spec["apl_delay_steps"]) is int and spec["apl_delay_steps"] == 18, "Wrong validation cohort or delay")
trial = legacy.read_trial(output, case, spec, kc_globals, cfg["neurons"], cfg["edges"])
try:
trial["timing"] = timing.validate_timing(output, spec, trial)
except Exception:
close_trial(trial)
raise
trial["record"] = dict(trial["record"], split=cohort, cohort=cohort, validation_cohort=cohort,
source_panel_split=spec["source_panel_split"], historical_never_simulated_claim=False,
used_for_parameter_selection=False)
if "source_panel_row" in spec:
trial["record"]["source_panel_row"] = spec["source_panel_row"]
return trial
def close_trial(trial):
if trial is None:
return
arrays = list(trial.get("apl", {}).values())
arrays += [trial.get("timing", {}).get(key) for key in ("applied", "pending")]
for value in arrays:
mmap = getattr(value, "_mmap", None)
if mmap is not None and not mmap.closed:
mmap.close()
def evidence_hashes(output, case, name, repeat):
files = ("state.npz", "summary.json", "tick-state-hashes.jsonl", "queue.jsonl", "requests.csv", "apl-component.json",
"apl-drive.float32.npy", "apl-state.float32.npy", "apl-inhibition.float32.npy",
"apl-applied.float32.npy", "apl-pending-tail.float32.npy", "apl-timing-audit.json")
return {"case": name, "repeat": repeat,
"input_sha256": {key: digest(case / key) for key in ("spec.json", "requests.npz", "pn-drive.npz")},
"output_sha256": {key: digest(output / key) for key in files}}
def collect_cohort(cohort, records, odors, cfg, exp, kc_globals, frozen_spec, legacy, timing):
"""Aggregate one block even when its representation gate fails."""
seeds = cfg["validation"]["seeds"]
failures, runs, rows, repeats, timings, proof, modes = [], {}, [], [], [], [], {}
for row in records:
name, first, spec = row["name"], None, None
case = exp / "cases" / cohort / name
try:
spec = validate_case(case, row, cfg, frozen_spec)
except Exception as error:
failures.append(dict(stage="case_input", case=name, type=type(error).__name__, message=str(error)))
for repeat_index in ([0, 1] if row["seed"] == seeds[0] else [0]):
trial = None
try:
require(spec is not None, "Case input validation unavailable")
output = exp / "gpu" / cohort / (name + "-r" + str(repeat_index))
trial = read_validation_trial(legacy, timing, output, case, spec, kc_globals, cfg)
require(trial["record"]["requested"] == row["requests"], "Inventory/actual request count differs")
entry = evidence_hashes(output, case, name, repeat_index)
proof.append(entry)
timings.append(dict(case=name, repeat=repeat_index, **trial["timing"]["report"]))
if repeat_index == 0:
first = trial
runs[(row["mode"], row["odor_id"], row["seed"])] = {key: trial[key] for key in
("kc_counts", "expected_external_events", "external_events")}
rows.append(trial["record"])
else:
require(first is not None, "Baseline unavailable for exact repeat")
report = dict(case=name, **timing.timing_repeat(first, trial, legacy))
repeats.append(report)
require(report["pass_all"] is True, "Exact repeat differs: " + ", ".join(
key for key, value in report["checks"].items() if not value))
except Exception as error:
failures.append(dict(stage="raw_trial" if repeat_index == 0 else "repeat_trial", case=name,
repeat=repeat_index, type=type(error).__name__, message=str(error)))
finally:
if trial is not first:
close_trial(trial)
close_trial(first)
for mode in MODES:
expected = {(mode, odor, seed) for odor in odors for seed in seeds}
if expected.issubset(runs):
try:
report = legacy.summarize_mode(mode, odors, seeds, runs, cfg["gates"])
require(report["conditions"] == legacy.evaluate_gates(report, cfg["gates"]), "Original gate conjunction mismatch")
require(report["within_distance_count"] == 60 and report["between_distance_count"] == 75 and
report["pair_count"] == 15 and all(pair["within_distance_count"] == 20 and
pair["between_distance_count"] == 5 for pair in report["pairs"]), "Pair-specific denominator changed")
modes[mode] = report
if not report["gate"]:
failures.append(dict(stage="representation_gate", mode=mode,
failed_conditions=[key for key, value in report["conditions"].items() if not value]))
except Exception as error:
failures.append(dict(stage="representation_calculation", mode=mode, type=type(error).__name__, message=str(error)))
numerical = bool(len(runs) == 60 and len(timings) == 72 and not any(row["stage"] in
("case_input", "raw_trial", "repeat_trial") for row in failures))
repeated = bool(len(repeats) == 12 and all(row["pass_all"] is True for row in repeats))
execution = bool(numerical and repeated and not any(row["stage"] == "representation_calculation" for row in failures))
represented = bool(len(modes) == 2 and all(row["gate"] is True for row in modes.values()))
return dict(cohort=cohort, source_panel_split=SPLITS[cohort], pass_all=bool(execution and represented),
execution_gate_pass=execution, numerical_integrity_pass=numerical, exact_repeat_pass=repeated,
representation_gate_pass=represented, original_representation_gate_pass=represented,
expected_base_trials=60, valid_base_trials=len(runs), expected_repeats=12, checked_repeats=len(repeats),
checked_timing_trials=len(timings), modes=modes, runs=rows, repeats=repeats, timing_checks=timings,
failures=failures, input_output_provenance=proof)
def summarize(cohort, out_json=_DEFAULT_OUTPUT):
"""Default exclusive write; None recomputes deterministically without writes."""
require(cohort in COHORTS, "Unknown validation cohort")
import context as ctx
target = ctx.EXP / "validation" / cohort / "summary.json" if out_json is _DEFAULT_OUTPUT else (
None if out_json is None else Path(out_json))
require(target is None or not target.exists(), "Refusing existing cohort summary")
result = dict(cohort=cohort, source_panel_split=SPLITS[cohort], pass_all=False, execution_gate_pass=False,
numerical_integrity_pass=False, exact_repeat_pass=False, representation_gate_pass=False,
original_representation_gate_pass=False, expected_base_trials=60, valid_base_trials=0,
expected_repeats=12, checked_repeats=0, checked_timing_trials=0,
modes={}, runs=[], repeats=[], timing_checks=[], failures=[], input_output_provenance=[])
proof, odors, encoder = {}, [], None
try:
ctx.check()
legacy = load_frozen(ctx.AG_MODEL / "calibration.py", AG_SHA256, "phase4ak_frozen_ag_calibration")
timing = load_frozen(ctx.AJ_MODEL / "calibration.py", AJ_SHA256, "phase4ak_frozen_aj_calibration")
inventory_path = ctx.EXP / "protocol/validation-cases.json"
encoder_path = ctx.EXP / "protocol/encoder-audit.json"
panel_path = ctx.ROOT / "experiments/phase4l-olfactory-grounding/odor-encoder/frozen-odor-panel.parquet"
require(digest(panel_path) == PANEL_SHA256, "Frozen static panel SHA changed")
import pandas as pd
panel = pd.read_parquet(panel_path).to_dict(orient="records")
inventory = validate_inventory(read(inventory_path), ctx.CFG, panel, legacy)
encoder = read(encoder_path)
validate_encoder(encoder, inventory, ctx.CFG)
seed_audit = ctx.MODEL / "seed-audit.json"
require(digest(seed_audit) == encoder["seeds_static_audit_sha256"], "Seed-audit receipt/encoder mismatch")
kc_path = ctx.AG / "apl-bundle/kc_globals.npy"
kc = np.load(kc_path, allow_pickle=False)
require(kc.dtype == np.int32 and kc.shape == (4064,) and np.all(np.diff(kc) > 0) and
np.all((kc >= 0) & (kc < ctx.CFG["neurons"])), "Frozen KC identity invalid")
base_path = ctx.AJ / "cases/delay18/cal-physiological-00-s51101/spec.json"
base = read(base_path)
require(base["apl_delay_steps"] == 18 and base["training"] is False, "Wrong frozen physical reference")
proof = {"validation_inventory": digest(inventory_path), "encoder_audit": digest(encoder_path),
"static_panel": digest(panel_path), "seed_audit": digest(seed_audit),
"KC_identity": digest(kc_path), "frozen_D18_spec": digest(base_path),
"AG_calibration_source": AG_SHA256, "AJ_calibration_source": AJ_SHA256}
odors = inventory[cohort]["odor_ids"]
result = collect_cohort(cohort, inventory[cohort]["records"], odors, ctx.CFG, ctx.EXP, kc, base, legacy, timing)
except Exception as error:
result["failures"].append(dict(stage="prerequisites", type=type(error).__name__, message=str(error)))
result.update(phase="4AK", apl_delay_steps=18, seeds=ctx.CFG["validation"]["seeds"], duration_ms=100.0,
odor_ids=odors, encoder_audit=encoder, prerequisite_input_sha256=proof,
representation_failure_is_not_numerical_failure=True, old_module_globals_modified=False,
old_heldout_dynamic_access=False, historical_never_simulated_claim=False,
requested_cohort_only_dynamic_read=True, suite_owns_sequential_unlock=True,
shared_apl_component_oracle_limit=True, independent_oracle_equivalence_claim=False,
seed_namespace_claim="Declared static-audit scope only; not an unqualified all-history independence claim",
biological_delay_measurement_claimed=False, candidate_generated=False, training=False,
metric_source="SHA-pinned AG complete phase4l gate; SHA-pinned AJ timing/repeat checks")
# Serializability/finiteness must be established even for read-only finalization.
json.dumps(result, allow_nan=False, sort_keys=True)
if target is not None:
outputs = {target: result}
outputs.update({target.parent / (mode + ".json"): report for mode, report in result["modes"].items()})
require(all(not path.exists() for path in outputs), "Refusing existing cohort/mode output")
for path, value in outputs.items():
ctx.save(path, value)
return result
if __name__ == "__main__":
require(len(sys.argv) == 2, "Usage: validation.py seed_validation|novel_to_aj")
answer = summarize(sys.argv[1])
print(json.dumps({key: answer[key] for key in ("cohort", "pass_all", "execution_gate_pass", "representation_gate_pass")}))
@@ -0,0 +1,49 @@
"""Unchanged deterministic-v2 reference rerun, exclusively into this new stage."""
import os
import sys
import time
import numpy as np
import pandas as pd
import yaml
from context import ROOT, EXP, CFG, check, save, bit_equal
def main():
check()
assert not (EXP / 'regression/frozen-five.json').exists()
from run_case import preflight
preflight()
runtime_path = ROOT / 'models/male-cns-lif/deterministic-runtime-v2'
pc = yaml.safe_load((runtime_path / 'phase4p.yaml').read_text())
sys.path.insert(0, str(ROOT / 'models/male-cns-lif'))
sys.path.insert(0, str(runtime_path))
import torch
import phase4p
assert torch.cuda.mem_get_info()[0] > 2 * 1024**3
torch.cuda.reset_peak_memory_stats()
started = time.perf_counter()
runtime = phase4p.CanonicalRuntime(pc, runtime_path, EXP)
rows = []
for spec in pc['reference_trials']:
preflight()
reference_dir = ROOT / 'experiments/phase4p-deterministic-runtime/phase4c-v2/reference' / spec['name']
events = pd.read_parquet(reference_dir / 'spike-events.parquet')
reference = dict(step=events.step.to_numpy(), neuron_idx=events.neuron_idx.to_numpy(),
counts=np.load(reference_dir / 'per-neuron-spike-counts.int32.npy'),
v=np.load(reference_dir / 'final-voltage.float32.npy'), g=np.load(reference_dir / 'final-g.float32.npy'))
result = runtime.run(np.flatnonzero(runtime.pops[spec['population']]), spec['rate_hz'], spec['seed'], spec['duration_ms'])
row = dict(trial=spec['name'], exact={key: bool(bit_equal(value, result[key])) for key, value in reference.items()},
dtype_shape={key: dict(reference_dtype=str(value.dtype), actual_dtype=str(result[key].dtype),
reference_shape=list(value.shape), actual_shape=list(result[key].shape)) for key, value in reference.items()},
wall_seconds=result['metrics']['wall_seconds'])
rows.append(row)
print(row, flush=True)
passed = len(rows) == 5 and all(all(row['exact'].values()) for row in rows)
save(EXP / 'regression/frozen-five.json', dict(pass_all=passed, trials=rows,
wall_seconds=time.perf_counter() - started, peak_allocated_vram=int(torch.cuda.max_memory_allocated()),
scope='Old frozen deterministic-v2 five references only; not the new D18 hypothesis'))
assert passed
if __name__ == '__main__':
main()