Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 09187e4d4d | |||
| b0728419fb | |||
| 7f341d7ffb | |||
| e7b2be7ee0 | |||
| 3fd58f2cf8 | |||
| 1e429fd50d | |||
| 703edfcb31 | |||
| 80aeb2093d | |||
| 0d3eca1c33 | |||
| 3e30934a55 | |||
| a9c5918445 | |||
| d54f0b3ef1 |
+24
-1
@@ -1,6 +1,29 @@
|
||||
# Digital Drosophila — 当前状态
|
||||
|
||||
更新:2026-09-30。独立分支:`codex/lif-author-semantics-lab`。
|
||||
更新:2026-10-01。独立分支:`codex/lif-author-semantics-lab`。
|
||||
|
||||
## 最新状态(取代下方历史摘要的“当前/下一步”表述)
|
||||
|
||||
Phase 4AQ 已封存为 **PASS-EXACT-UPDATED-BOUNDARY-ENGINEERING-NOT-LEARNING**。Phase 4AR 的普通嗅觉 acquisition 已登记并启动,仍在执行;学习成功尚未判定,没有新 learned candidate。
|
||||
|
||||
2026-10-01 00:09:04(Asia/Shanghai)的只读账本观察:
|
||||
|
||||
- 已提交 **411/30,000** 轮训练(包含每轮更新和独立 CPU 校验)。
|
||||
- 已提交 **62/3,920** 次独立 probe。
|
||||
- 实际进程检查确认监督器、协调器和一个子进程存在;该未提交子进程不计入上述完成量。
|
||||
- 无 stopped、最终退出或 execution-complete 记录。登记 SHA 和 16 个登记源码 SHA 全部匹配;没有执行全量输入或历史产物完整性审计。
|
||||
|
||||
登记 SHA-256:`b63e6281b6505ca3b60acb467dd0b3fae274cf513dcbfd653649ba52e9ba9740`。登记科学源码提交:`80aeb2093db655329774eff7b32fb6e417b8b40b`。这与当前仓库文档提交是不同概念;后续文档提交不会替换已登记源码版本。
|
||||
|
||||
CPU 常驻原型的小范围工程验证已完成,原型未接入当前实验,也不据此更改当前运行速度或完成时间估计。
|
||||
|
||||
下一步保持原登记执行,不自动重试、不调参或读取中途学习指标。真实完整退出后,再独立进行科学 gate 和最终完整性审计。普通 acquisition 本身不自动授权后续 assay、游戏、RL、decoder 或 Web/3D。
|
||||
|
||||
[AR 登记范围](docs/progress/phase4ar-normal-acquisition.md) · [AQ 封存结果](docs/progress/phase4aq-execution-boundary.md) · [最新运行快照](registry/phase4ar-runtime-observation-20261001T000904/snapshot.json) · [本次同步说明](docs/progress/repository-sync-20261001.md) · [CPU 原型边界](docs/progress/conditioning-cpu-residency-probe-20260930.md)
|
||||
|
||||
Git 仍仅同步代码、文档和小证据。本次没有上传大型原始数据或完整运行轨迹,也没有启用 Git LFS;不代表完成全量异机备份。下方截至 Phase 4AP 的原文作为历史摘要保留,其中“尚未启动条件化”等状态已经由本节取代。
|
||||
|
||||
## 以下为截至 Phase 4AP 的历史摘要
|
||||
|
||||
## 最近已封存结果
|
||||
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
面向 MaleCNS v1.0 的可审计连接组、LIF 模型、感觉接口与局部可塑性机制研究。
|
||||
**这是研究工程仓库,不是已经实现自主学习或游戏控制的果蝇。**
|
||||
|
||||
截至 2026-09-29,最新封存阶段是 **Phase 4Z:COMPLETE-EVENT-RESOLVED-PN-AUDIT**。
|
||||
截至 2026-10-01 00:09(Asia/Shanghai),最新封存阶段是 **Phase 4AQ:PASS-EXACT-UPDATED-BOUNDARY-ENGINEERING-NOT-LEARNING**。
|
||||
**Phase 4AR 普通嗅觉 acquisition 正在执行,科学结论未判定**:采样时已提交 411/30,000 轮训练及 CPU 校验、62/3,920 次独立 probe;不是实时自动更新计数。
|
||||
最新研发分支为 `codex/lif-author-semantics-lab`,远端默认分支仍为初始化分支。本页状态不表示已完成分支合并。
|
||||
项目顶层验收口径为 **5/10(50%)**;这不是生物学逼真度、工作量完成率或剩余工期。
|
||||
最新正式候选运行时为 `MaleCNS-LIF-runtime-v2-deterministic-candidate`。
|
||||
`MaleCNS-TemporalEligibility-v2-candidate` 与 `MaleCNS-OlfactoryEncoder-v1-candidate` 保留。
|
||||
@@ -13,7 +15,8 @@
|
||||
|
||||
| 主题 | 文档 |
|
||||
|---|---|
|
||||
| 当前状态、验收比例、下一步 | [项目状态](docs/00-overview/status.md) |
|
||||
| 最新运行状态、证据与下一步 | [当前状态](CURRENT.md)、[本次同步说明](docs/progress/repository-sync-20261001.md) |
|
||||
| 顶层验收比例与历史基线 | [项目状态](docs/00-overview/status.md) |
|
||||
| 目录和数据流 | [架构与目录](docs/00-overview/architecture.md) |
|
||||
| 科学数据定义和来源 | [数据契约](docs/10-data/data-contract.md)、[来源登记](docs/10-data/provenance.md) |
|
||||
| 模型边界 | [模型与冻结契约](docs/20-model/baseline.md) |
|
||||
@@ -35,7 +38,7 @@
|
||||
|
||||
服务器项目根目录:`/data/digital-drosophila/`。
|
||||
远程:`ssh://git@192.168.10.31:2222/qishizhe/digital-drosophila.git`。
|
||||
初始化分支:`codex/project-bootstrap`。
|
||||
初始化/当前远端默认分支:`codex/project-bootstrap`;最新研发分支:`codex/lif-author-semantics-lab`。
|
||||
|
||||
Git 保存源代码、配置、文档、书目、阶段证据副本和逐文件哈希清单。
|
||||
**Git 不保存原始 SWC/Feather、CSR、完整事件/状态、模型 checkpoint、虚拟环境或大型压缩包。**
|
||||
@@ -45,7 +48,7 @@ Git 保存源代码、配置、文档、书目、阶段证据副本和逐文件
|
||||
## 安全的首次检查
|
||||
|
||||
```bash
|
||||
git clone --branch codex/project-bootstrap ssh://git@192.168.10.31:2222/qishizhe/digital-drosophila.git
|
||||
git clone --branch codex/lif-author-semantics-lab ssh://git@192.168.10.31:2222/qishizhe/digital-drosophila.git
|
||||
cd digital-drosophila
|
||||
python3 -B tools/repo_guard.py
|
||||
```
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
# CPU 常驻原型性能验证(2026-09-30)
|
||||
|
||||
## 结论与边界
|
||||
|
||||
结果:`PASS-CPU-RESIDENCY-PROTOTYPE-ONLY`。这是独立工程原型,不是新的
|
||||
学习候选、GPU runtime 验收或 Phase 4AR 替换授权。原型没有执行脑模拟,
|
||||
没有修改或安装权重,没有读取 AR 中途学习指标,也没有减少任何文件校验。
|
||||
|
||||
当前正式 AR 继续原样执行;不能将此原型热替换到已登记的执行账本中。
|
||||
常驻任务 ACK 与真实进程退出属于不同证据,不能把前者伪装成每轮 OS exit。
|
||||
|
||||
## 方法
|
||||
|
||||
- 使用已封存 AQ 的 `mechanical--fresh-parent` 和
|
||||
`performance--natural-light-fresh` 两个预先指定工程 checkpoint。
|
||||
- 固定 7 组:M、N、M、N_D0、N_frozen、M_D0、M。
|
||||
- M 的 before 为零 overlay;N 使用实际 AP 历史 learned overlay。
|
||||
- D0/frozen 是在独立 authority 中声明的工程命令变体,保留原 sealed events,
|
||||
不修改原文件,不重新运行 conditioning。
|
||||
- 更新器调用原 `E.postprocess_epoch`,只复用同身份的已验证模块。
|
||||
- 原 AQ fresh-process validator 对每组原型输出独立重算并实际退出 0。
|
||||
- 新 resident validator 使用独立 PID;数学和校验主体与原实现 AST 一致,
|
||||
仅调整模块复用与来源声明。所有动态输入、校验和 U 重算仍逐次执行。
|
||||
- CPU 单线程、低优先级、CUDA 不可见且未初始化。两常驻 worker 串行接收任务,
|
||||
更新器和验证器不混载同一个解释器。
|
||||
|
||||
## 真实计时
|
||||
|
||||
首次请求单列为冷启动;下表为后 6 组配对热态均值。fresh 与 resident 的
|
||||
父级请求计时均包括请求/响应保存、输入摘要与输出核验;fresh 另外包含
|
||||
其每次进程启动/ready/退出。resident 生命周期启动与退出另有实际记录。
|
||||
|
||||
| CPU 环节 | fresh 原实现 | resident 原型 |
|
||||
|---|---:|---:|
|
||||
| Epoch 更新 | 4.672 秒 | 2.763 秒 |
|
||||
| 独立校验 | 3.995 秒 | 2.063 秒 |
|
||||
| 合计 | 8.667 秒 | 4.826 秒 |
|
||||
|
||||
- 两阶段均常驻:该 CPU 段加速 **1.796×**,耗时下降约 **44.3%**。
|
||||
- 只常驻更新器、仍保留 fresh 原验证器:该 CPU 段加速 **1.283×**。
|
||||
- 整个有界原型实测约 100.46 秒;服务器 benchmark 父进程实际退出 0。
|
||||
- 这些数值不包括全脑 GPU 模拟、AP 外层包装和 AR ledger 开销,不能据此
|
||||
声称全实验加速 1.8 倍,或将原 9 天预测直接除以 1.8。
|
||||
- 正式 AR 同时运行,且仅测试两个源轨迹、一个 compartment,结果是小样本
|
||||
工程测量,不是所有条件的性能保证。
|
||||
|
||||
## 一致性与完整性
|
||||
|
||||
- 本地和服务器安全/AST 单元测试:12/12 通过。
|
||||
- 7/7 真实全尺寸 CPU 回放:四个更新文件 SHA 完全相同;delta 的 dtype、
|
||||
shape、raw bytes 完全相同;完整 update receipt、trace 摘要相同。
|
||||
- 原始 M/N 同时与已封存 AQ 更新输出比较,完全相同。
|
||||
- D0/frozen 的 before/after delta 逐位不变,包含非零历史 delta 条件。
|
||||
- 两验证器的科学校验字段完全相同;仅白名单列出的 schema/source/cache
|
||||
provenance 字段不同,明确不冒称新验证器为原 frozen verifier。
|
||||
- 14 次 fresh 进程及 2 个 resident 进程均由父级观察实际退出 0。
|
||||
- 170 个新产物的清单、大小、SHA 已独立复核;消费的冻结输入及原型源代码
|
||||
在前后保持原 SHA。这里不声称重新扫描了全部历史 Phase 1–4AQ。
|
||||
- 23:26 北京时间,AR 的 16 个已登记源码仍匹配原 SHA;原 supervisor /
|
||||
controller 441824/441825 活跃,累计 310 个已验证 epoch、50 个 probe,
|
||||
没有 stopped 记录。本段是时间限定快照,不是实时状态或学习结论。
|
||||
|
||||
## 保存位置
|
||||
|
||||
- 代码:`tools/conditioning-perf-lab-v1/`
|
||||
- 执行源码提交:`7f341d7ffbacc4b46bca74e5f570f7f2e8108ac0`
|
||||
- 原始执行目录:`/tmp/malecns-cpu-residency-woqIQa/`(保留,未删除)。
|
||||
- 持久化证据副本:`registry/conditioning-perf-prototype-20260930/`。
|
||||
- 主要结果:该目录的 `report.json`、`benchmark-plan.json`、`manifest.json`。
|
||||
- 副本不重写原回执中的实际执行路径。Git 同步代码及小型 JSON 证据;NPZ
|
||||
按现有仓库策略保留在服务器,不把 Git 同步描述成所有数据异机备份。
|
||||
|
||||
## 下一步
|
||||
|
||||
优先验证静态图/APL 的常驻加载和独立 GPU worker 状态重置,但这需要不与
|
||||
当前正式任务争抢 4090 的测试窗口,以及逐事件、状态和更新的一致性回归。
|
||||
没有进行这一测试前,不升级为正式 runtime,也不终止或改写当前 AR。
|
||||
@@ -0,0 +1,47 @@
|
||||
# Phase 4AQ:更新边界与连续状态验证
|
||||
|
||||
数值审计结果:`PASS-EXACT-UPDATED-BOUNDARY-ENGINEERING-NOT-LEARNING`。
|
||||
|
||||
这意味着权重更新、延迟队列、连续神经状态和探测分叉的工程接口通过了本次固定实验;不代表已经实现关联学习、记忆保持或可用游戏控制。本阶段没有产生 learned candidate,没有调学习率、阈值、APL 参数或扩大 plastic mask。
|
||||
|
||||
## 已验证的结果
|
||||
|
||||
- 新代码的服务器 CPU 测试:189/189 通过;证据发布工具另有 11/11 合成测试通过。
|
||||
- 实际执行 23 次全脑运行、7 个 CPU 更新/复核进程、1 个 GPU 输入采样进程,共 31 个独立子进程。
|
||||
- 全脑规模保持 166,700 neurons、25,582,938 edges;新运行合计 125,200 ticks,dt=0.1 ms。
|
||||
- 14 项数值和来源检查均通过。独立连续 oracle 与 reference/light 恢复运行的事件、终态与队列一致;D(t)=0/frozen 对照与旧 continuation 一致。
|
||||
- 固定机械诊断中,1 条真实候选边发生更新,off-compartment 更新为 0。KC neuron_idx=3986 在 tick 1199 发放,经真实 edge_id=2802165 到 neuron_idx=9,在 tick 1217 被接受:精确延迟 18 steps。到达使用更新后权重,而不是重新缩放已经存在的 g。
|
||||
- 实际执行 1 s + 9 s 连续静置,以及 t=0/1/10 s 的 A/B 探测。探测不添加 US,不进行更新,不反馈到静置轨迹。这不是完整 retention 学习实验。
|
||||
- 所有实际运行有限值检查通过。连续静置记录的 peak allocated VRAM 为 518,003,712 bytes(约 494 MiB);这不是整个 GPU 的总占用量。
|
||||
- 有限执行器自身记录用时 842.1341 s;不包含此前准备、此后的独立审计和最终封存时间。
|
||||
|
||||
## 成本与下一步
|
||||
|
||||
固定 fresh/light 训练周期(brain + 原 E 更新 + 独立 CPU 复核)记录为 24.7712 s,新增产物 3,350,283 bytes;无 US 的 fresh/light 探测为 10.3950 s,新增产物 2,797,824 bytes。
|
||||
|
||||
审计补入周期收据和保守的编译缓存费用后,两个周期分别按 5,078,099 / 4,522,528 bytes 计费。以相邻周期开始时间作为尾部完成上界后,训练为 32.9680 s(其中保守重复计入中间约 8.20 s 的输入采样),探测为 10.4098 s。以上均不是整个 normal suite 的工期承诺。
|
||||
|
||||
正式预算报告保持 `INSUFFICIENT-MEASUREMENTS / FUTURE-POLICY-NOT-REGISTERED`:不能把 4 GiB/7200 s 的本次有限诊断限额当作长期训练授权,也不能忽略逐步增长的目录扫描、最终校验和未知活动量。
|
||||
|
||||
下一步是登记并实现正式 normal conditioning 执行器:保留固定 30,000 training/control epochs、3,920 probes、全部种子和对照;使用追加式产物清单避免每轮重扫全部历史目录,并保留最终全量 SHA-256 核验。不得通过减少种子、缩短试验、删除证据或调参来取得 PASS。学习判据仍以刺激特异性的 MBON 与非 MBON 下游响应为准,不能仅凭 delta-weight 改变。
|
||||
|
||||
## 保存位置与完整性边界
|
||||
|
||||
- 新模型代码:`models/male-cns-lif/conditioning-execution-v1/`
|
||||
- 新实验:`experiments/phase4aq-conditioning-execution/`
|
||||
- 小证据归档:`registry/phase4aq-conditioning-execution/`
|
||||
- 正式封存状态与哈希:实验下 `audit/final-status.json`、`manifest.json`、`checksums.sha256`;发布凭证在 registry 下 `publication-receipt.json`。
|
||||
- 原始数据没有写入;登记范围内的旧阶段冻结产物与源文件的独立事后完整性检查通过。旧五组 numerical reference 的 AM 封存证据被保留并核验,**不是本阶段重新执行了那五组试验**。
|
||||
- Git 同步包含代码、文档和小证据。完整数值数组仍在服务器,**Git 不构成全量数据备份**。
|
||||
|
||||
代码提交:`d54f0b3ef13d5b70ffca80ea83a679eb9ab37e20`。
|
||||
|
||||
注册 SHA-256:`dad0ba33ded8c6725662c419525ef4185a6ff169042a402c18d0bd760dad7358`。
|
||||
|
||||
数值报告 SHA-256:`57ed41acf0e3617c2c2c70a43684a0d9b2ea775e9ab3d83ab84a960200e50063`。
|
||||
|
||||
最终报告 SHA-256:`dcbb58f296bd0d51e3c8757f0c45dd5585b3a76f8c2a0b5881f4c14076721882`。
|
||||
|
||||
实验 manifest SHA-256:`2dc0feca75f718f2ee0d7c9240da503221823573fd25f1344d2fd97d97eb2db7`。已封存 790 个 payload 文件、463,441,109 bytes;封存前重新计算数值/预算审计,并在独立进程再次核验旧阶段完整性。
|
||||
|
||||
本次独立工程验证没有证明模型已经能够学习;后续条件化结果必须另行真实执行、审计并报告。
|
||||
@@ -0,0 +1,87 @@
|
||||
# Phase 4AR:独立分支普通嗅觉条件化
|
||||
|
||||
## 当前状态
|
||||
|
||||
2026-09-30:新分支代码已提交并同步远程仓库;服务器整套 CPU 测试
|
||||
73/73 通过,0 失败、0 跳过。旧封存完整性检查通过,实验预注册已锁定。
|
||||
4,080 份固定 CS 输入已生成并由真实进程退出记录及账本确认。
|
||||
独立后台执行器已启动;尚未据此宣称训练完成或学习成功。
|
||||
|
||||
启动后观察到 4 个训练 epoch 已完成原更新及独立 CPU 校验、6 次独立
|
||||
probe 已提交;后续仍在运行。这是有时间边界的启动快照,不是当前实时
|
||||
累计数,也不是科学 gate 结果。首轮实际 CPU 校验确认使用封存 spike events
|
||||
重算原 U 更新,父进程记录退出码为 0。
|
||||
|
||||
- 模型:`/data/digital-drosophila/models/male-cns-lif/normal-conditioning-v1/`
|
||||
- 实验:`/data/digital-drosophila/experiments/phase4ar-normal-conditioning/`
|
||||
- 管理日志:`/data/digital-drosophila/logs/phase4ar-normal-conditioning/`
|
||||
- 源码提交:`80aeb2093db655329774eff7b32fb6e417b8b40b`
|
||||
- 预注册 SHA-256:`b63e6281b6505ca3b60acb467dd0b3fae274cf513dcbfd653649ba52e9ba9740`
|
||||
- 仓库分支:`codex/lif-author-semantics-lab`
|
||||
|
||||
## 固定实验与边界
|
||||
|
||||
这是用户授权的独立动力学假设分支,不是替换 reference/runtime,
|
||||
也不是重新解释旧阶段失败。Phase 1–4AQ 封存产物、base graph、原始权重、
|
||||
transmitter sign、14,232-edge mask、eligibility-v2 与 APL 参数保持只读。
|
||||
|
||||
按既有固定计划执行 physiological / matched-energy、PAM15 / PPL103、
|
||||
A+/B− 与 B+/A−、5 个训练重复,共 40 个 block。A 为 4-ethylphenol,
|
||||
B 为 3-hexanone。PAM15/PPL103 功能预测是明确的 compartment-specific
|
||||
模型假设,不能推广成“所有 PAM 为正、所有 PPL 为负”。
|
||||
|
||||
7 组实际执行的实验臂为 paired、D=0、frozen、random reward、unpaired、
|
||||
CS-only、DAN-only,共 30,000 训练/对照 epoch、3,920 次独立 A/B probe。
|
||||
每 epoch 120 ms,CS 为前 100 ms,人工 US 为 90 ms;每轮重置神经状态,
|
||||
仅携带经独立 CPU 验证的 plastic delta。Probe 无 US、无学习更新、无反馈。
|
||||
|
||||
终点固定,不允许根据中间结果改参数、改种子或挑最好条件。普通 acquisition
|
||||
通过也不等于已经获得可用学习模型;不会自动启动 reversal、retention、
|
||||
delayed reward 或任何游戏、动作解码器、RL、视觉、Web/3D。
|
||||
|
||||
## 可审计执行
|
||||
|
||||
当前登记包含 16 份源码、63 项输入身份、33 份准备产物。登记之后不得
|
||||
修改这些文件来修复运行中的实验;失败必须保留证据,不能原地改后续试跑。
|
||||
|
||||
每个子进程先写独占开始记录,再保存真实退出状态、输入/输出 SHA-256、
|
||||
不可变顺序账本。部分失败保留,不自动重试。训练依次运行原 brain、
|
||||
原 E/U 更新和独立 CPU 重算;不能用父进程中自报成功代替真实退出。
|
||||
|
||||
仅使用已登记的 RTX 4090,逐次检查 ComfyUI 队列,不停止其他服务。
|
||||
新输出上限 256 GiB、磁盘保留至少 100 GiB、单子进程上限 1,800 秒,
|
||||
登记期限 21 天。约 9 天仅为少量 AQ 计时的线性规划估算,并非全条件实测。
|
||||
|
||||
完整性核验与 CPU 测试是工程证据,不是新数值回归,更不是学习证据。
|
||||
最终必须另行进行全产物审计、固定学习 gate 分析及旧阶段完整性复核。
|
||||
仓库同步源码/文档/小型证据,不等于大体量实验数据已经异机备份。
|
||||
|
||||
## 后续只读检查
|
||||
|
||||
已安排本线程每小时检查,仅在实质进展、异常、完成或需人工操作时提醒。
|
||||
不自动重试、修补已注册源码、进入后续 assay 或声明学习成功。
|
||||
|
||||
独立只读工具位于 `tools/normal-conditioning-audit/progress_normal.py`,
|
||||
8 项临时数据测试在服务器通过。它读取实际提交账本与最新退出记录,
|
||||
不读取大体量脑输出;其进度结果不是完整性报告或科学结论。
|
||||
正在执行的 child 在没有真实退出记录时明确保持 UNKNOWN,不能由 PID
|
||||
或一个提前写出的 results 文件推定成功。完整 run 完成后仍需最终独立审计。
|
||||
|
||||
## 终审工具准备进展(不改变正在运行的实验)
|
||||
|
||||
独立终审工具已完成服务器联合测试:42/42 通过,0 失败、0 跳过。
|
||||
其中学习结果判定测试通过冻结的原指标代码生成六神经元合成报告,
|
||||
包含正常通过、终点未达 3/5、单一 H 对照来源失败、严格等号不通过等情形。
|
||||
这些不是本次真实学习结果,也没有读取中途学习指标。
|
||||
|
||||
`tools/normal-conditioning-audit/normal_finalize.py check` 已在服务器实测:
|
||||
发现注册进程仍在运行后按设计拒绝终审,未创建终审输出目录。
|
||||
真正的完整审计和固定 gate 分析只能在全部任务结束、实际退出为 0 后进行。
|
||||
终审产物将位于独立的 `phase4ar-normal-conditioning-final-audit/`,
|
||||
不会向已完成的原实验目录追加或替换文件。
|
||||
|
||||
终审保留原账本的全部字段,不改 PASS/FAIL 标志;完成记录在账本检查后
|
||||
才生成这一文件边界由单独的真实文件清单核对。任何额外文件、变更、
|
||||
未完成进程或来源矛盾均不得被当成完整的学习阳性/阴性结论。
|
||||
即便普通 acquisition 通过,delayed/reversal/retention 仍未运行,不能
|
||||
生成候选模型、宣称学习已经可用或自动启动后续实验。
|
||||
@@ -0,0 +1,37 @@
|
||||
# 仓库同步与运行观察 — 2026-10-01
|
||||
|
||||
采样时间:2026-10-01 00:09:04(Asia/Shanghai,UTC+08:00)。本报告是运行状态快照,不是新的科学结论,也不是完整数据备份。
|
||||
|
||||
## 本轮新增内容
|
||||
|
||||
- 发布独立的 [Phase 4AR 运行观察](../../registry/phase4ar-runtime-observation-20261001T000904/snapshot.json)。
|
||||
- 更新仓库 README 和 CURRENT 的入口状态,保留旧阶段报告与历史事实。
|
||||
- 未修改科学源码、配置、输入、权重或 Phase 1–4AQ 封存产物;未重启、重试或停止 Phase 4AR。
|
||||
- 未将 CPU 常驻性能原型接入当前登记实验。
|
||||
|
||||
## 已提交执行账本
|
||||
|
||||
| 项目 | 完成量 | 登记总量 |
|
||||
|---|---:|---:|
|
||||
| 训练轮次(神经运行、更新及独立 CPU 校验均已提交) | 411 | 30,000 |
|
||||
| 独立 probe | 62 | 3,920 |
|
||||
|
||||
采样时操作系统确认监督器、协调器和一个子进程存在。子进程仍未提交,不能加入完成数;PID 或结果文件存在不构成完成证据。无 stopped 记录、无最终退出记录、无 execution-complete 记录。因此仍是运行中,学习成功尚未判断。
|
||||
|
||||
登记 SHA-256:`b63e6281b6505ca3b60acb467dd0b3fae274cf513dcbfd653649ba52e9ba9740`。
|
||||
登记科学源码提交:`80aeb2093db655329774eff7b32fb6e417b8b40b`。
|
||||
本次直接核对登记的 16 个源码文件 SHA-256,全部匹配;63 个输入 pin 和 33 个准备文件 pin 仅记录登记数量,没有再次全量读取、哈希或重跑。实验所在文件系统可用约 602.45 GiB,这不是整台服务器总容量。
|
||||
|
||||
## 观察边界
|
||||
|
||||
这是一次非原子的在线元数据观察;读取期间未观察到账本条目增加,但不因此声称取得文件系统原子快照。只读取登记、账本、绑定的少量回执和任务身份,不读取 spike/state/delta 数组,不评估中途学习指标,不挑选条件,不调整策略。
|
||||
|
||||
正式科学 gate 与最终历史完整性审计须在真实完整退出后独立执行。执行完成不等于学习成功;不自动开始反转、延迟奖励、保持或游戏等后续任务。
|
||||
|
||||
## 同步范围和分支
|
||||
|
||||
当前研发分支:`codex/lif-author-semantics-lab`。远端:`ssh://git@192.168.10.31:2222/qishizhe/digital-drosophila.git`。
|
||||
|
||||
采样前本地与该远端分支均为 `b0728419fb4caaef37e41e3989b138c3fc6f754e`,已有代码、报告与小证据并无漏推。远端默认分支仍为 `codex/project-bootstrap`;本轮不合并、不改默认分支。
|
||||
|
||||
本轮只发布本报告、入口文档及元数据快照。raw、SWC、CSR、权重和完整实验轨迹仍未通过 Git 上传,未配置或迁移 Git LFS。完整异机数据备份未因此完成。后续如启用 LFS,需要单独检查服务配置、可用空间与归档方案,不改动冻结数据原件。
|
||||
@@ -0,0 +1,178 @@
|
||||
# Conditioning execution branch — bounded preparation protocol
|
||||
|
||||
Status: DRAFT, NOT REGISTERED, NO GPU EXECUTION AUTHORITY YET.
|
||||
|
||||
This is a new independent model branch authorized by the user. All previously
|
||||
registered sources, raw data, frozen brains and experiment artifacts remain
|
||||
read-only. Existing scientific failures remain failures. The completed AP
|
||||
interface test does not establish functional learning.
|
||||
|
||||
## Scope and the next scientific decision
|
||||
|
||||
Consolidate updated-weight/same-state continuation, fixed functional gates and
|
||||
measured complete-process resource costs in this package. Then register and run
|
||||
the already proposed normal acquisition and all six controls, for all eight
|
||||
cells and five independent training replicates. Do not keep replacing functional
|
||||
learning experiments with unbounded engineering milestones.
|
||||
|
||||
No learning-rate, threshold, gain, transmitter, anatomical weight, input-rate,
|
||||
odor, mask, APL calibration or eligibility-v2 changes are permitted by this
|
||||
package. Any future biological dynamics hypothesis requires a separately named
|
||||
model/version and a pre-outcome hypothesis; permission for a new branch does not
|
||||
reclassify a changed model as an exact optimization of the old one.
|
||||
|
||||
No games, decoder, RL, visual stimulation, web services or 3D are included.
|
||||
|
||||
## Exact boundary semantics
|
||||
|
||||
- A fresh, sealed neural epoch and its actual original E postprocess identify
|
||||
the one permitted update. Recompute original U from the actual sealed spike
|
||||
events in a separate CPU interpreter, without executing the brain or E again.
|
||||
- Install original base plus the full after-delta once, using the frozen
|
||||
float32-mV to float64-SI bridge. Never add the after-delta to old effective
|
||||
weights. Keep the original 14,232 existing candidate edges and fixed floor.
|
||||
- Preserve voltage, existing g, refractory state, pending spike ring, APL state,
|
||||
complete APL pending amplitudes and absolute tick. Counts/events are explicitly
|
||||
segment-local in the new recording, not falsely lifetime counts.
|
||||
- Already accumulated g is not recomputed or rescaled. Pending presynaptic spike
|
||||
flags use current weights when they arrive, exactly as the frozen runtime
|
||||
does. Already queued APL amplitudes are preserved. The delays remain 18 steps;
|
||||
the spike ring has 19 slots and the APL ring has 18.
|
||||
- Later idle continuations retain the same after-overlay. A probe can fork a
|
||||
checkpoint but cannot become an idle ancestor. No analytical time advance.
|
||||
- New checkpoints use their own explicit updated-boundary schema. They do not
|
||||
claim the original C fixed-weight boundary rule was satisfied.
|
||||
|
||||
The independent oracle re-executes the exact fresh parent prefix, never calls
|
||||
restore, verifies live prefix state/events against that parent, changes only
|
||||
the authorized weights once and executes the unchanged reference timestep loop.
|
||||
Its explicit within-run weight switch is diagnostic, not a production backend.
|
||||
The one added boundary hook is independently removed to verify exact AST
|
||||
rollback. Its honest `within_trial_weight_updates=true` admission is not passed
|
||||
off as an unchanged-weight checkpoint.
|
||||
|
||||
## Bounded validation inventory
|
||||
|
||||
Use sealed AP reference epoch-001 parents for D1, D0 and frozen. New outputs never
|
||||
go into AP. Compare D1 restored reference/light 100 ms suffixes to a fresh
|
||||
220 ms continuous oracle. Compare D0/frozen new reference/light suffixes to
|
||||
original C fixed-weight continuation. Compare all events and final state/queues
|
||||
exactly; compare per-tick hashes, request acceptance, CSR queue and APL traces
|
||||
where actually recorded. Do not claim light records unseen intermediate states.
|
||||
|
||||
AP D1 epoch-001 has 765 spikes in its final 18 ticks, but none from its 79
|
||||
changed-edge sources. Thus it has useful real pending queues but cannot alone
|
||||
prove updated-weight handling on a pending changed candidate edge.
|
||||
|
||||
Add one deterministic mechanical diagnostic parent: 120 ms fresh dynamics with
|
||||
no requests until tick 1199, then one requested spike in the minimum canonical
|
||||
KC source ID among actual y5B'2a candidates, together with the four verified
|
||||
PAM15 DAN IDs. Run original U with US at tick 1199, D=1 and the unchanged rule.
|
||||
This is a test fixture stimulus, not a new odor or a learning-success trial.
|
||||
No seed search or parameter adjustment follows missing coverage. Require a
|
||||
real changed existing candidate edge, a real source spike crossing the boundary,
|
||||
and an accepted timed arrival. Nonempty queues alone are insufficient. Compare
|
||||
its restored reference/light suffixes to the independent continuous oracle.
|
||||
|
||||
Also run actual no-input 1 s then 9 s idle dynamics from AP D1, preserving one
|
||||
lineage. At 0, 1 and 10 s fork A/B no-US/no-update 120 ms probes. The two saved
|
||||
evaluation inputs use the original first block's distinct evaluation streams
|
||||
from master 20260930, the original L physiological rate tables and [0,100 ms)
|
||||
CS window; no sampler is run until registration. Repeated probes are not new
|
||||
training seeds and never feed back to the idle chain.
|
||||
|
||||
The bounded engineering suite does not run acquisition or claim retention of
|
||||
a learned association. A failure is preserved with partial outputs; no silent
|
||||
retry, replacement seed or post-result trial selection is allowed.
|
||||
|
||||
Two fixed measurement calls avoid extrapolating incomplete or mismatched costs.
|
||||
Re-execute AP D1 epoch-001's original saved natural input from a fresh state and
|
||||
its recorded before-overlay, using light recording followed by original E and
|
||||
the independent CPU validator. Compare its events, final state and actual delta
|
||||
to AP. Separately measure one fresh-state/no-US A evaluation probe with the
|
||||
original zero overlay. Retention-continuation probes are not substituted for
|
||||
normal fresh-state probe costs. These measurements are engineering diagnostics,
|
||||
not additional acquisition or a seed search.
|
||||
|
||||
The complete proposed inventory is 23 new brain calls / 125,200 ticks, seven
|
||||
CPU update/validation children and one GPU sampler process (two uniform batches):
|
||||
31 child processes. Compilation caches may evolve and are inventoried separately;
|
||||
previous scientific outputs remain immutable. All future checkpoints/hashes are
|
||||
derived from actual completed children, not fabricated during registration.
|
||||
|
||||
## Functional gates fixed before acquisition
|
||||
|
||||
`learning_gates.py` retains the frozen normal/delayed predicates, requires five
|
||||
independent training replicates, checks full 63-bit stream identities and keeps
|
||||
evaluation streams separate. A majority means at least three replicates each
|
||||
satisfy the entire conjunction, not different seeds passing different clauses.
|
||||
|
||||
Two explicit additional operationalizations are fixed before outcomes:
|
||||
|
||||
1. Reversal and real-time retention use nonMBONDownstream for the downstream
|
||||
functional gate, while reporting the entire legacyDownstream union as well.
|
||||
MBON-local change cannot be counted twice as downstream transfer.
|
||||
2. The legacy H mean-control predicate is called separately for the PAM15 and
|
||||
PPL103 control sources in each (input mode, reinforced cue) group. Both must
|
||||
pass that separate audit. No control pooling or favorable-source selection.
|
||||
|
||||
Reversal keeps the original conditioned-minus-neutral orientation and original
|
||||
pre baseline, with strict nonzero sign crossing and no-reversal continuation
|
||||
remaining on its original side. Retention requires the same replicate to pass
|
||||
both 1 s and 10 s against time-matched frozen controls. Delta change alone is
|
||||
never a functional learning gate. See the pinned original PROTOCOL_DRAFT and
|
||||
EVALUATION_POLICY_DRAFT for the complete unchanged input/assay inventory.
|
||||
|
||||
Pure gate functions authenticate neither disk/process evidence nor anatomy;
|
||||
their results explicitly say conditional predicates, not scientific PASS.
|
||||
The eventual coordinator must bind completed real trajectories and input,
|
||||
population, seed, delta and checkpoint receipts before making a learning claim.
|
||||
|
||||
## Resource accounting and stop policy
|
||||
|
||||
Proposed bounded validation cap: 4 GiB of new outputs, at least 10 GiB free
|
||||
reserve, 1,800 seconds per child and 7,200 seconds total. Confirm measured free
|
||||
space and commit the registration before execution. Use only the admitted
|
||||
RTX 4090, check all three ComfyUI queues and do not stop or evict services.
|
||||
|
||||
Measure parent wall time from before spawn through actual exit and independent
|
||||
result validation, including input hashing, CUDA startup/compilation, graph load,
|
||||
CPU update verification, lossless compression and I/O. Worker/core timing is a
|
||||
separate field. No extrapolation may label GPU-only time as complete latency.
|
||||
|
||||
The proposed normal suite has 30,000 training/control epochs plus 3,920 probes:
|
||||
33,920 brain calls and 4,070.4 biological seconds. The full proposal has 68,000
|
||||
epochs, 9,440 probes and 80 actual 10 s idle lineages, totaling 11,892.8 biological
|
||||
seconds before engineering validation. These are inventory arithmetic, not wall
|
||||
time or disk measurements. Predeclare a finite normal-run resource budget using
|
||||
measured complete outputs, a stated reserve and explicit uncertainty about
|
||||
learning-dependent activity. No unbounded automatic launch is authorized here.
|
||||
|
||||
If normal acquisition fails the registered all-cell gate, preserve and seal the
|
||||
actual failure; delayed/reversal/retention are NOT-RUN. Do not tune to rescue it.
|
||||
If it passes, run the already registered follow-up matrix. Frozen integrity and
|
||||
required numerical regressions remain independent gates, not learning evidence.
|
||||
|
||||
## Provenance
|
||||
|
||||
Before registration require every new source to match its recorded Git commit,
|
||||
snapshot the protocol and sources, and pin all old inputs by SHA-256. Record
|
||||
actual child exits; worker self-receipts do not prove their own process exited.
|
||||
All output files receive SHA-256 and an exact manifest at sealing. No old source
|
||||
or runtime global is patched. Full experimental arrays remain server-side;
|
||||
source/evidence Git synchronization must not be described as a bulk-data backup.
|
||||
|
||||
`audit_execution.py` reads actual recorded process exits and full output hashes;
|
||||
`prepare_execution.py integrity` runs in a separate CPU process after execution.
|
||||
`finalize_execution.py` requires externally supplied registration, numerical,
|
||||
budget and after-integrity report hashes and creates an exclusive experiment
|
||||
seal. The entire model directory is not itself claimed sealed: every registered
|
||||
source is bound to its committed blob and sealed source snapshot instead.
|
||||
|
||||
`budget_report.py` may return insufficient information rather than invent future
|
||||
large-suite overhead. A few measured cycles cannot establish the cost of a
|
||||
growing full-directory hash policy, unknown learning-dependent activity or final
|
||||
integrity work. No normal-suite resource assumptions or execution authorization
|
||||
are implicitly supplied by this finite engineering registration. Real measured
|
||||
cycle cost and conservative accounting bounds must still be reported even when
|
||||
a credible reserved complete-suite projection is unavailable.
|
||||
@@ -0,0 +1,491 @@
|
||||
"""Read-only, process-bound finite engineering audit; never a learning gate.
|
||||
|
||||
Only the optional final JSON is written, exclusively. The recorded successful
|
||||
parent-process exits are authenticated file evidence, not re-observed exits.
|
||||
Old integrity/sealing is deliberately a separate process. No E, U or Torch is
|
||||
imported here; all checkpoint loading shares updated_continuation.C.R.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
import sys
|
||||
from types import ModuleType
|
||||
|
||||
import numpy as np
|
||||
|
||||
import boundary_compare as B
|
||||
import boundary_plan as PLAN
|
||||
import execution_authority as A
|
||||
import isolated_execution as W
|
||||
import updated_continuation as D
|
||||
from prepare_execution import EXP, MODEL, LAB, save
|
||||
|
||||
N, EDGES = 166700, 25582938
|
||||
require, read, digest = A.require, A.read, A.digest
|
||||
|
||||
|
||||
def canonical(value):
|
||||
return json.dumps(value, sort_keys=True, separators=(',', ':'), ensure_ascii=False, allow_nan=False)
|
||||
|
||||
|
||||
def same_json(left, right):
|
||||
return canonical(left) == canonical(right)
|
||||
|
||||
|
||||
def verify_pins(pins):
|
||||
require(type(pins) is dict and pins, 'Nonempty input authority required')
|
||||
for path, sha in pins.items():
|
||||
require(A.pin(path)['sha256'] == sha, 'Pinned file changed: ' + str(path))
|
||||
|
||||
|
||||
def tree(directory):
|
||||
root = Path(directory)
|
||||
require(root.is_dir(), 'Missing output tree')
|
||||
result = {}
|
||||
for p in sorted(root.rglob('*')):
|
||||
require(not any(q.is_symlink() or (hasattr(q, 'is_junction') and q.is_junction())
|
||||
for q in (p, *p.parents)), 'Linked evidence forbidden')
|
||||
if p.is_file():
|
||||
result[p.relative_to(root).as_posix()] = dict(sha256=digest(p), bytes=p.stat().st_size)
|
||||
else:
|
||||
require(p.is_dir(), 'Nonregular evidence forbidden')
|
||||
require(result, 'Empty output tree')
|
||||
return result
|
||||
|
||||
|
||||
def _helpers():
|
||||
raw = W.AP.read_bytes()
|
||||
require(hashlib.sha256(raw).hexdigest() == W.AP_SHA, 'Frozen worker helper changed')
|
||||
module = ModuleType('_conditioning_execution_audit_pure_worker_helpers')
|
||||
module.__file__ = str(W.AP)
|
||||
exec(compile(raw, str(W.AP), 'exec'), module.__dict__)
|
||||
return module
|
||||
|
||||
|
||||
def expected_processes(plan):
|
||||
calls = {row['call_id']: row for row in plan['calls']}
|
||||
require(len(calls) == len(plan['calls']), 'Duplicate call')
|
||||
kinds = {name: ('brain' if row['runner'] in ('runtime_light', 'fresh_probe') else
|
||||
'oracle' if row['runner'] == 'boundary_oracle' else
|
||||
'unchanged' if row['runner'] == 'runtime_continuation' else 'updated')
|
||||
for name, row in calls.items()}
|
||||
for arm in ('D1', 'D0', 'frozen'):
|
||||
kinds['AP-' + arm + '--cpu-verify'] = 'validate_cpu'
|
||||
for name in ('mechanical--fresh-parent', 'performance--natural-light-fresh'):
|
||||
kinds[name + '--original-E'] = 'update'
|
||||
kinds[name + '--cpu-verify'] = 'validate_cpu'
|
||||
kinds['evaluation-inputs'] = 'sample'
|
||||
require(len(kinds) == plan['counts']['total_children'], 'Planned child inventory differs')
|
||||
return kinds
|
||||
|
||||
|
||||
def _closure(reg, reg_sha):
|
||||
return {**reg['source_sha256'], **reg['input_sha256'], **reg['prepared_file_sha256'],
|
||||
str(EXP / 'protocol/preregistered.json'): reg_sha}
|
||||
|
||||
|
||||
def verify_process(name, kind, reg, reg_sha, process_path, helper):
|
||||
"""Recheck actual bytes; never accept worker pass flags as a seal."""
|
||||
paths = {key: EXP / f'{sub}/{name}{suffix}' for key, sub, suffix in (
|
||||
('job', 'jobs', '.json'), ('worker', 'receipts', '.worker.json'),
|
||||
('process', 'receipts', '.process.json'), ('stdout', 'logs', '.stdout.log'),
|
||||
('stderr', 'logs', '.stderr.log'))}
|
||||
require(Path(process_path) == paths['process'], 'Wrong fixed process record path')
|
||||
job, receipt, process = (read(paths[k]) for k in ('job', 'worker', 'process'))
|
||||
ap = kind in ('brain', 'update')
|
||||
script = W.AP if ap else MODEL / 'isolated_execution.py'
|
||||
worker_sha = W.AP_SHA if ap else reg['source_sha256'][str(script)]
|
||||
schema = 'phase4ap-isolated-worker-job-v1' if ap else W.SCHEMA
|
||||
require(job['schema'] == schema and job['job_id'] == name and job['kind'] == kind and
|
||||
job['registration_sha256'] == reg_sha and job['worker_sha256'] == worker_sha,
|
||||
'Actual job identity differs')
|
||||
require(process['schema'] == 'conditioning-execution-process-v1' and process['complete'] is True and
|
||||
process['exit_code'] == 0 and type(process['exit_code']) is int and process['timed_out'] is False and
|
||||
process['name'] == name and process['kind'] == kind and process['registration_sha256'] == reg_sha,
|
||||
'Missing successful recorded process exit')
|
||||
job_sha = digest(paths['job'])
|
||||
require(process['job_sha256'] == job_sha and process['worker_receipt_sha256'] == digest(paths['worker']) and
|
||||
all(process[k + '_sha256'] == digest(paths[k]) for k in ('stdout', 'stderr')), 'Process file chain changed')
|
||||
argv = process['argv']
|
||||
require(type(argv) is list and len(argv) == (8 if ap else 7) and type(argv[0]) is str and bool(argv[0]),
|
||||
'Recorded process command is incomplete')
|
||||
require(argv[1:] == ['-B', str(script), *([kind] if ap else []), '--job', str(paths['job']),
|
||||
'--job-sha256', job_sha], 'Recorded command differs from pinned worker/job')
|
||||
expected_schema = 'phase4ap-isolated-worker-receipt-v1' if ap else 'conditioning-isolated-execution-receipt-v1'
|
||||
require(receipt['schema'] == expected_schema and receipt['complete'] is True and
|
||||
all(receipt[k] == job[k] for k in ('job_id', 'kind', 'registration_sha256', 'worker_sha256')) and
|
||||
receipt['job_sha256'] == job_sha and receipt['process_exit_independently_observed'] is False,
|
||||
'Worker receipt identity/scope differs')
|
||||
closure = _closure(reg, reg_sha)
|
||||
require(all(job['input_sha256'].get(p) == s for p, s in closure.items()), 'Registered input closure omitted')
|
||||
inputs = dict(closure)
|
||||
if kind == 'brain':
|
||||
roles = ('runtime_light', 'runtime_continuation')
|
||||
case = Path(job['case_dir'])
|
||||
extra = [case / 'spec.json', case / 'requests.npz', Path(job['overlay_file']), Path(job['overlay_manifest'])]
|
||||
inputs.update({str(p): digest(p) for p in extra})
|
||||
else:
|
||||
authority = Path(job['authority_file'])
|
||||
require(digest(authority) == job['authority_sha256'], 'Worker authority changed')
|
||||
inputs[str(authority)] = job['authority_sha256']
|
||||
value = read(authority)
|
||||
if kind == 'sample':
|
||||
require(authority == EXP / 'protocol/preregistered.json' and job['authority_sha256'] == reg_sha,
|
||||
'Sampler is not bound to actual registration')
|
||||
else:
|
||||
inputs.update(A.files_from_authority(value))
|
||||
if kind == 'validate_cpu':
|
||||
update = Path(job['update_dir'])
|
||||
require({p.name for p in update.iterdir()} == set(D.UPDATE_FILES), 'Update must contain exact four files')
|
||||
inputs.update({str(p): digest(p) for p in update.iterdir()})
|
||||
require(job['chain_sha256'] == digest(update / 'chain-receipt.json'), 'CPU chain pin differs')
|
||||
if kind == 'oracle':
|
||||
case = Path(job['oracle_case'])
|
||||
for filename, key in (('spec.json', 'oracle_spec_sha256'), ('requests.npz', 'oracle_requests_sha256')):
|
||||
require(digest(case / filename) == job[key], 'Live oracle case pin differs')
|
||||
inputs[str(case / filename)] = job[key]
|
||||
roles = ('conditioning_epoch',) if kind == 'update' else ()
|
||||
require(job['input_sha256'] == inputs, 'Actual job has missing/undeclared input authority')
|
||||
pins = {**inputs, str(paths['job']): job_sha, str(script): worker_sha}
|
||||
if ap:
|
||||
expected_sources = {n: dict(path=str(LAB / (n + '.py')), sha256=helper.SOURCE_PINS[n]) for n in roles}
|
||||
require(job['sources'] == expected_sources and receipt['source_files'] == expected_sources, 'Frozen process source differs')
|
||||
pins.update({v['path']: v['sha256'] for v in expected_sources.values()})
|
||||
else:
|
||||
require(set(job['source_sha256']) == W.SOURCES[kind], 'New worker source inventory differs')
|
||||
for filename, sha in job['source_sha256'].items():
|
||||
require(reg['source_sha256'][str(MODEL / filename)] == sha, 'New source not registered')
|
||||
pins[str(MODEL / filename)] = sha
|
||||
pins[str(W.AP)] = W.AP_SHA
|
||||
require(receipt['verified_input_sha256' if ap else 'input_sha256'] == pins, 'Worker did not check the complete actual closure')
|
||||
verify_pins(pins)
|
||||
if kind == 'unchanged':
|
||||
W.bind_unchanged_authority(helper, job, dict(authority=Path(job['authority_file']),
|
||||
checkpoint=Path(job['checkpoint_dir']), case=Path(job['case_dir']),
|
||||
overlay_file=Path(job['overlay_file']), overlay_manifest=Path(job['overlay_manifest'])),
|
||||
{Path(p): sha for p, sha in pins.items()})
|
||||
expected_output = EXP / ('updates' if kind == 'update' else 'runs') / name.removesuffix('--original-E')
|
||||
require(Path(job['output_dir']) == expected_output and receipt['output_dir'] == str(expected_output) and
|
||||
job['receipt_file'] == str(paths['worker']), 'Output or receipt escaped fixed inventory')
|
||||
outputs = tree(expected_output)
|
||||
hashes = {k: v['sha256'] for k, v in outputs.items()}
|
||||
require(hashes == receipt['output_files_sha256'] and process['output_bytes'] == sum(v['bytes'] for v in outputs.values()) and
|
||||
process['output_inventory_sha256'] == hashlib.sha256(json.dumps(hashes, sort_keys=True).encode()).hexdigest(),
|
||||
'Full output inventory changed')
|
||||
attempt = Path(str(paths['worker']) + '.attempt.json')
|
||||
require(digest(attempt) == receipt['attempt_sha256'], 'Attempt record changed')
|
||||
av = read(attempt)
|
||||
require(av['complete'] is False and av['job_sha256'] == job_sha and av['no_automatic_retry'] is True,
|
||||
'Attempt record does not bind actual invocation')
|
||||
require(receipt.get('scientific_learning_pass_claimed', receipt.get('scientific_gate_pass_claimed')) is False,
|
||||
'Worker claims a scientific gate')
|
||||
for key in ('child_wall_seconds', 'end_to_end_seconds', 'validation_wall_seconds'):
|
||||
require(type(process[key]) in (float, int) and np.isfinite(process[key]) and process[key] >= 0, 'Invalid recorded timing')
|
||||
evidence = {str(p): digest(p) for p in (*paths.values(), attempt)}
|
||||
return dict(name=name, kind=kind, paths=paths, job=job, receipt=receipt, process=process,
|
||||
output=expected_output, output_inventory=outputs, evidence_sha256=evidence, input_pins=pins)
|
||||
|
||||
|
||||
def _npz(path):
|
||||
with np.load(path, allow_pickle=False) as archive:
|
||||
return {name: archive[name].copy() for name in archive.files}
|
||||
|
||||
|
||||
def _pair(left, right):
|
||||
B._complete(left); B._complete(right)
|
||||
checks, observed = B.C._pair_checks(left, right)
|
||||
exact = all(checks.values())
|
||||
return dict(numerical_exact=exact, pass_all=exact, checks=checks,
|
||||
failed_checks=[k for k, v in checks.items() if not v], observed=observed,
|
||||
light_intermediate_states_observed=False, learning_pass_claimed=False)
|
||||
|
||||
|
||||
def _parent(reg, complete, role):
|
||||
record = complete['parents'][role]
|
||||
if role in reg['parent_records']:
|
||||
original = reg['parent_records'][role]
|
||||
require(all(same_json(record[k], v) for k, v in original.items()), 'Imported parent declaration changed')
|
||||
return record
|
||||
|
||||
|
||||
def _update_check(parent, verified, cpu_name):
|
||||
"""Bind actual CPU recomputation process to original E four-file evidence."""
|
||||
cpu = verified[cpu_name]
|
||||
require(cpu['kind'] == 'validate_cpu', 'Missing independent CPU update verification process')
|
||||
directory = Path(parent['update_dir']); hashes = {n: digest(directory / n) for n in D.UPDATE_FILES}
|
||||
require(set(p.name for p in directory.iterdir()) == set(D.UPDATE_FILES), 'Unexpected update inventory')
|
||||
require(parent['after_overlay'] == dict(overlay_file=str(directory / 'delta-after.npz'),
|
||||
overlay_manifest=str(directory / 'overlay-manifest.json')), 'After snapshot paths leave actual E update')
|
||||
authority = parent['epoch_authority']; epoch = read(authority['path'])
|
||||
require(A.pin(authority['path']) == authority and cpu['job']['authority_file'] == authority['path'] and
|
||||
cpu['job']['authority_sha256'] == authority['sha256'] and Path(cpu['job']['update_dir']) == directory and
|
||||
cpu['job']['chain_sha256'] == hashes['chain-receipt.json'], 'CPU verification points to another update')
|
||||
chain, update = (read(directory / name) for name in ('chain-receipt.json', 'update-receipt.json'))
|
||||
report = read(cpu['output'] / 'validation.json')
|
||||
require(same_json(report, cpu['receipt']['result']) and report['schema'] == 'conditioning-update-cpu-validation-v1' and
|
||||
report['complete'] is True and report['epoch_authority_sha256'] == authority['sha256'] and
|
||||
report['parent_checkpoint_manifest_sha256'] == parent['checkpoint_sha256'] and
|
||||
report['update_files_sha256'] == hashes and report['frozen_U_verify_receipt_recomputed'] is True and
|
||||
report['actual_sealed_events_used'] is True and report['full_candidate_mapping_verified'] is True and
|
||||
report['brain_executed'] is False and report['learning_pass_claimed'] is False and
|
||||
report['frozen_U_source_sha256'] == D.SOURCE_PINS['conditioning_update_source'] and
|
||||
report['validator_source'] == A.pin(MODEL / 'validate_update_cpu.py'), 'CPU recomputation receipt mismatch')
|
||||
require(chain.get('schema') == 'phase4an-epoch-postprocess-chain-v1' and chain['complete'] is True and
|
||||
all(chain[k] is False for k in ('weights_installed', 'brain_executed', 'learning_pass_claimed', 'candidate_generated')) and
|
||||
chain['authority_sha256'] == authority['sha256'] and chain['source_neural_checkpoint_dir'] == parent['directory'] and
|
||||
chain['source_neural_checkpoint_manifest_sha256'] == parent['checkpoint_sha256'] and
|
||||
chain['output_files_sha256'] == {k: v for k, v in hashes.items() if k != 'chain-receipt.json'} and
|
||||
chain['update_receipt_payload_sha256'] == report['update_receipt_payload_sha256'] == update['payload_sha256'],
|
||||
'Original E chain no longer binds the same update')
|
||||
before = _npz(parent['before_overlay']['overlay_file']); after = _npz(parent['after_overlay']['overlay_file'])
|
||||
require(set(before) == set(after) == {'edge_id', 'plastic_delta_mv'} and
|
||||
B.bit_equal(before['edge_id'], after['edge_id']), 'Overlay identity changed')
|
||||
require(report['before_overlay_sha256'] == digest(parent['before_overlay']['overlay_file']) and
|
||||
report['before_manifest_sha256'] == digest(parent['before_overlay']['overlay_manifest']) and
|
||||
report['after_overlay_sha256'] == hashes['delta-after.npz'] and
|
||||
report['after_manifest_sha256'] == hashes['overlay-manifest.json'] and
|
||||
report['before_delta_raw_sha256'] == B._raw(before['plastic_delta_mv']) and
|
||||
report['after_delta_raw_sha256'] == B._raw(after['plastic_delta_mv']), 'Actual delta differs from CPU verification')
|
||||
require(update['payload_sha256'] == hashlib.sha256(canonical({k: v for k, v in update.items() if k != 'payload_sha256'}).encode()).hexdigest(),
|
||||
'Update receipt payload changed')
|
||||
require(epoch['checkpoint_dir'] == parent['directory'] and epoch['checkpoint_manifest_sha256'] == parent['checkpoint_sha256'],
|
||||
'Update is not from actual neural parent')
|
||||
return dict(pass_all=True, CPU_process=cpu_name, update_files_sha256=hashes,
|
||||
before_delta_raw_sha256=report['before_delta_raw_sha256'], after_delta_raw_sha256=report['after_delta_raw_sha256'],
|
||||
U_receipt_payload_sha256=update['payload_sha256'], U_recomputed_in_this_audit=False,
|
||||
U_recomputation_from_authenticated_separate_CPU_process=True)
|
||||
|
||||
|
||||
def outcome(checks, pending):
|
||||
"""Numerical failure and missing nonvacuous coverage are not equivalent."""
|
||||
require(type(checks) is dict and bool(checks) and all(type(v) is bool for v in checks.values()),
|
||||
'Explicit nonempty numerical/lineage checks required')
|
||||
require(set(pending) == {'D1', 'mechanical'}, 'Both predetermined pending-edge audits required')
|
||||
exact = all(checks.values())
|
||||
coverage = pending['mechanical']['accepted_changed_edge_witness_verified'] is True
|
||||
status = 'FAIL-NUMERICAL-OR-LINEAGE' if not exact else ('PASS-EXACT-UPDATED-BOUNDARY-ENGINEERING-NOT-LEARNING'
|
||||
if coverage else 'INCOMPLETE-CHANGED-EDGE-COVERAGE')
|
||||
return exact, coverage, status
|
||||
|
||||
|
||||
def _pending(parent, child, parent_descriptor):
|
||||
epoch = read(parent_descriptor['epoch_authority']['path']); spec = read(epoch['files']['spec']['path'])
|
||||
graph = Path(spec['graph_dir']); apl_dir = Path(spec['apl_bundle_dir']); arrays = {}
|
||||
try:
|
||||
for name in ('ptr', 'src', 'dst', 'edge_id', 'weights'):
|
||||
arrays[name] = np.load(graph / (name + '.npy'), mmap_mode='r', allow_pickle=False)
|
||||
apl = np.load(apl_dir / 'apl_globals.npy', allow_pickle=False)
|
||||
before = _npz(parent_descriptor['before_overlay']['overlay_file'])
|
||||
after = _npz(parent_descriptor['after_overlay']['overlay_file'])
|
||||
require(B.bit_equal(before['edge_id'], after['edge_id']), 'Changed witness candidate mask differs')
|
||||
paths = [graph / (n + '.npy') for n in arrays] + [apl_dir / 'apl_globals.npy',
|
||||
Path(parent_descriptor['before_overlay']['overlay_file']), Path(parent_descriptor['after_overlay']['overlay_file'])]
|
||||
return B.audit_changed_pending(parent, child, ptr=arrays['ptr'], src=arrays['src'], dst=arrays['dst'],
|
||||
edge_id=arrays['edge_id'], base_weights=arrays['weights'], apl_mask=np.isin(arrays['src'], apl),
|
||||
candidate_edge_id=before['edge_id'], delta_before=before['plastic_delta_mv'],
|
||||
delta_after=after['plastic_delta_mv'], input_pins={str(p): digest(p) for p in paths})
|
||||
finally:
|
||||
for value in arrays.values():
|
||||
value._mmap.close()
|
||||
|
||||
|
||||
def _lineage(reg, complete, verified, records):
|
||||
"""Actual advancing idle chain plus non-feedback probes, not memory success."""
|
||||
checks = {}; probe_rows = []
|
||||
base = reg['parent_records'][reg['plan']['imported_parents']['D1']['role']]
|
||||
delta = {k: digest(v) for k, v in base['after_overlay'].items()}
|
||||
sampler = verified['evaluation-inputs']; sr = read(sampler['output'] / 'sampler-receipt.json')
|
||||
require(same_json(sr, sampler['receipt']['result']) and sr['complete'] is True and sr['registration_sha256'] == sampler['job']['registration_sha256'] and
|
||||
sr['uniform_batch_calls'] == 2 and sr['US_added'] is False and sr['brain_executed'] is False,
|
||||
'Sampler receipt changed or wrong scope')
|
||||
for cue in ('A', 'B'):
|
||||
sample = sampler['output'] / (cue + '-requests.npz')
|
||||
rows = [r for r in sr['rows'] if r['cue'] == cue]
|
||||
require(len(rows) == 1 and rows[0]['saved_requests_sha256'] == digest(sample), 'Sampler cue binding differs')
|
||||
req = _npz(sample); rates = _npz(EXP / f'inputs/static/{cue}-rates.npz')
|
||||
require(set(req) == {'tick', 'neuron_idx'} and req['tick'].dtype == req['neuron_idx'].dtype == np.int32 and
|
||||
req['tick'].shape == req['neuron_idx'].shape and np.all((req['tick'] >= 0) & (req['tick'] < 1000)) and
|
||||
np.isin(req['neuron_idx'], rates['targets']).all(), 'Probe contains non-CS or out-of-window input')
|
||||
require(rows[0]['stream']['seed'] == reg['plan']['evaluation_streams'][cue]['seed'] and
|
||||
rows[0]['stream']['semantic_key'] == reg['plan']['evaluation_streams'][cue]['key'] and
|
||||
rows[0]['stream']['split'] == 'evaluation', 'Probe seed semantic binding differs')
|
||||
for label in ('t0', 't1', 't10'):
|
||||
name = f'D1--probe--{label}--{cue}'; call = next(c for c in reg['plan']['calls'] if c['call_id'] == name)
|
||||
job = verified[name]['job']; auth = read(job['authority_file'])
|
||||
case = Path(auth['case']['requests']['path'])
|
||||
parent = _parent(reg, complete, call['parent'])
|
||||
checks[name + '.input_bytes'] = digest(case) == digest(sample)
|
||||
checks[name + '.parent_clock'] = auth['parent'] == dict(directory=parent['directory'], checkpoint_manifest_sha256=parent['checkpoint_sha256']) and auth['global_tick_offset'] == call['global_tick_offset']
|
||||
checks[name + '.fixed_delta'] = auth['overlay_after']['file']['sha256'] == delta['overlay_file'] and auth['overlay_after']['manifest']['sha256'] == delta['overlay_manifest']
|
||||
checks[name + '.no_update_US_backflow'] = call['US'] is call['plastic_update'] is call['feedback_to_idle'] is False and not records[name]['summary']['within_trial_weight_updates']
|
||||
probe_rows.append(dict(call_id=name, global_tick_offset=records[name]['global_tick_offset'],
|
||||
actual_CS_requests=len(req['tick']), actual_US_requests=0, inputs_sha256=digest(case),
|
||||
complete_response_metrics_or_retention_gate=False))
|
||||
for name in ('D1--idle--1s', 'D1--idle--9s'):
|
||||
call = next(c for c in reg['plan']['calls'] if c['call_id'] == name)
|
||||
auth = read(verified[name]['job']['authority_file']); parent = _parent(reg, complete, call['parent'])
|
||||
req = _npz(auth['case']['requests']['path'])
|
||||
checks[name + '.actual_duration'] = records[name]['steps'] == call['steps']
|
||||
checks[name + '.parent_clock'] = auth['parent'] == dict(directory=parent['directory'], checkpoint_manifest_sha256=parent['checkpoint_sha256']) and auth['global_tick_offset'] == call['global_tick_offset']
|
||||
checks[name + '.empty_input'] = len(req['tick']) == len(req['neuron_idx']) == 0
|
||||
checks[name + '.fixed_delta'] = auth['overlay_after']['file']['sha256'] == delta['overlay_file'] and auth['overlay_after']['manifest']['sha256'] == delta['overlay_manifest']
|
||||
checks['no_probe_feeds_other_segment'] = all('--probe--' not in str(c.get('parent')) for c in reg['plan']['calls'])
|
||||
checks['ten_seconds_actually_advanced'] = records['D1--idle--1s']['steps'] + records['D1--idle--9s']['steps'] == 100000 and records['D1--idle--9s']['summary']['global_next_tick'] == 101200
|
||||
perf = verified['performance--evaluation-A-light-fresh']['job']
|
||||
checks['normal_probe_performance_actual_A_bytes'] = digest(Path(perf['case_dir']) / 'requests.npz') == digest(sampler['output'] / 'A-requests.npz')
|
||||
checks['normal_probe_performance_zero_overlay'] = perf['overlay_file'] == reg['initial_overlay']['overlay_file'] and perf['overlay_manifest'] == reg['initial_overlay']['overlay_manifest']
|
||||
return dict(pass_all=all(checks.values()), checks=checks, failed_checks=[k for k, v in checks.items() if not v],
|
||||
probes=probe_rows, biological_retention_demonstrated=False, learning_pass_claimed=False,
|
||||
light_per_tick_identity_claimed=False, one_and_nine_second_same_state_lineage_verified=all(checks.values()))
|
||||
|
||||
|
||||
def audit(reg_sha, *, save_report=True):
|
||||
require(sys.dont_write_bytecode and 'torch' not in sys.modules and 'conditioning_epoch' not in sys.modules,
|
||||
'Run a fresh pure CPU Python -B audit process')
|
||||
regfile = EXP / 'protocol/preregistered.json'
|
||||
require(digest(regfile) == reg_sha, 'External registration SHA changed')
|
||||
reg = read(regfile); PLAN.validate_plan(reg['plan'])
|
||||
require(reg['schema'] == 'conditioning-execution-registration-v1' and reg['engineering_only'] is True and
|
||||
reg['scientific_acquisition_authorized'] is False, 'Not an engineering-only authority')
|
||||
pins = _closure(reg, reg_sha); verify_pins(pins)
|
||||
complete_path = EXP / 'audit/execution-complete.json'; complete_sha = digest(complete_path); complete = read(complete_path)
|
||||
calls = reg['plan']['calls']; expected = expected_processes(reg['plan'])
|
||||
require(complete['complete'] is True and complete['registration_sha256'] == reg_sha and
|
||||
complete['completed_calls'] == [c['call_id'] for c in calls] and set(complete['processes']) == set(expected) and
|
||||
complete['scientific_learning_pass_claimed'] is complete['candidate_generated'] is False,
|
||||
'Execution inventory incomplete or scientifically overclaimed')
|
||||
helper = _helpers(); verified = {name: verify_process(name, kind, reg, reg_sha, complete['processes'][name], helper)
|
||||
for name, kind in expected.items()}
|
||||
records = {}; imports = {}; checks = {}; updates = {}; comparisons = {}; pending = {}; used_pins = dict(pins)
|
||||
for item in verified.values():
|
||||
for path, sha in {**item['input_pins'], **item['evidence_sha256']}.items():
|
||||
require(path not in used_pins or used_pins[path] == sha, 'Conflicting actual process authority')
|
||||
used_pins[path] = sha
|
||||
try:
|
||||
for arm, descriptor in reg['plan']['imported_parents'].items():
|
||||
parent = _parent(reg, complete, descriptor['role'])
|
||||
require(str(Path(parent['directory']) / 'checkpoint-manifest.json') == descriptor['checkpoint_manifest'] and
|
||||
parent['checkpoint_sha256'] == descriptor['sha256'], 'Imported authority differs')
|
||||
D.C.load_checkpoint(parent['directory'], descriptor['sha256'])
|
||||
imports[arm] = B.load_record(parent['directory'], kind='parent')
|
||||
updates['AP-' + arm] = _update_check(parent, verified, 'AP-' + arm + '--cpu-verify')
|
||||
for call in calls:
|
||||
name = call['call_id']; run = verified[name]; directory = run['output']; receipt = run['receipt']
|
||||
case = EXP / 'cases' / call['case_group']
|
||||
expected_spec = read(reg['case_templates'][call['case_group']])
|
||||
if call['parent'] is not None:
|
||||
p = _parent(reg, complete, call['parent'])
|
||||
expected_spec.update(parent_checkpoint_manifest_sha256=p['checkpoint_sha256'],
|
||||
global_tick_offset=call['global_tick_offset'])
|
||||
require(same_json(read(case / 'spec.json'), expected_spec), 'Executed case drifted from registered template')
|
||||
if run['kind'] in ('brain', 'unchanged'):
|
||||
require(Path(run['job']['case_dir']) == case, 'Wrong registered runtime case')
|
||||
elif run['kind'] == 'oracle':
|
||||
require(Path(run['job']['oracle_case']) == case, 'Wrong registered oracle case')
|
||||
else:
|
||||
auth = read(run['job']['authority_file'])
|
||||
require(auth['case'] == dict(spec=A.pin(case / 'spec.json'), requests=A.pin(case / 'requests.npz')) and
|
||||
auth['boundary_id'] == name and auth['registration_sha256'] == reg_sha and
|
||||
auth['diagnostic_mode'] == call['diagnostic_mode'] and auth['input_policy'] == call['input_policy'] and
|
||||
auth['transition'] == call['transition'] and auth['parent'] == dict(directory=p['directory'],
|
||||
checkpoint_manifest_sha256=p['checkpoint_sha256']), 'Boundary authority differs from actual registered call')
|
||||
if call['runner'] == 'boundary_oracle':
|
||||
manifest = read(directory / 'oracle-manifest.json')
|
||||
actual = {k: v['sha256'] for k, v in tree(directory).items() if k != 'oracle-manifest.json'}
|
||||
require(manifest == dict(schema='conditioning-live-oracle-files-v1', complete=True, files_sha256=actual),
|
||||
'Live oracle exact manifest differs')
|
||||
kind = 'oracle'
|
||||
else:
|
||||
checkpoint_sha = receipt['result']['checkpoint_manifest_sha256']
|
||||
D.load_checkpoint(directory, checkpoint_sha)
|
||||
kind = 'updated' if call['runner'] == 'updated_continuation' else 'parent'
|
||||
record = B.load_record(directory, kind=kind); records[name] = record; B._complete(record)
|
||||
require(record['steps'] == call['steps'] and record['global_tick_offset'] == call['global_tick_offset'] and
|
||||
record['summary']['nodes'] == N and record['summary']['edges'] == EDGES and
|
||||
record['summary']['diagnostic_mode'] == call['diagnostic_mode'], 'Actual graph/clock/mode differs from registered call')
|
||||
if call['runner'] == 'updated_continuation':
|
||||
declared = _parent(reg, complete, name)
|
||||
require(declared['directory'] == str(directory) and declared['checkpoint_sha256'] == checkpoint_sha,
|
||||
'Saved parent registry differs from actual checkpoint')
|
||||
helper._verify_precision(receipt['environment'], record['summary']['apl_component']['environment'])
|
||||
cycle = read(EXP / 'receipts' / (name + '.cycle.json'))
|
||||
used_pins[str(EXP / 'receipts' / (name + '.cycle.json'))] = digest(EXP / 'receipts' / (name + '.cycle.json'))
|
||||
require(cycle['complete'] is True and same_json(cycle['call'], call) and cycle['source_registration_sha256'] == reg_sha,
|
||||
'Complete-cycle descriptor mismatch')
|
||||
for relative, evidence in cycle['output_inventory'].items():
|
||||
path = EXP / relative
|
||||
require(path.is_relative_to(EXP) and '..' not in Path(relative).parts and
|
||||
evidence == dict(sha256=digest(path), bytes=path.stat().st_size), 'Cycle immutable output changed')
|
||||
for name in ('mechanical--fresh-parent', 'performance--natural-light-fresh'):
|
||||
parent = _parent(reg, complete, name)
|
||||
require(parent['directory'] == str(verified[name]['output']) and parent['checkpoint_sha256'] == records[name]['manifest_sha256'],
|
||||
'New E source parent identity differs')
|
||||
updates[name] = _update_check(parent, verified, name + '--cpu-verify')
|
||||
worker = verified[name + '--original-E']
|
||||
require(worker['output'] == Path(parent['update_dir']) and
|
||||
worker['receipt']['result']['chain_receipt_sha256'] == digest(worker['output'] / 'chain-receipt.json'),
|
||||
'Original E actual process output differs')
|
||||
for arm in ('D1', 'mechanical'):
|
||||
oracle = records[arm + '--live-oracle']
|
||||
parent = imports['D1'] if arm == 'D1' else records['mechanical--fresh-parent']
|
||||
descriptor = _parent(reg, complete, reg['plan']['imported_parents']['D1']['role'] if arm == 'D1' else 'mechanical--fresh-parent')
|
||||
original_authority = Path(verified[arm + '--updated--reference']['job']['authority_file'])
|
||||
auth = read(original_authority)
|
||||
for mode in ('reference', 'light'):
|
||||
name = arm + '--updated--' + mode; authority = Path(verified[name]['job']['authority_file'])
|
||||
comparisons[arm + '-live-vs-' + mode] = B.compare_boundary(oracle, records[name], parent=parent,
|
||||
expected_before_sha256=auth['expected_effective_weight_before_sha256'],
|
||||
expected_after_sha256=auth['expected_effective_weight_after_sha256'],
|
||||
paired_authorities=(original_authority.read_bytes(), authority.read_bytes()))
|
||||
pending[arm] = _pending(parent, records[arm + '--updated--reference'], descriptor)
|
||||
for arm in ('D0', 'frozen'):
|
||||
for mode in ('reference', 'light'):
|
||||
comparisons[arm + '-old-C-vs-' + mode] = _pair(records[arm + '--old-C--reference'], records[arm + '--updated--' + mode])
|
||||
performance = 'performance--natural-light-fresh'
|
||||
comparisons['performance-natural-vs-AP'] = _pair(imports['D1'], records[performance])
|
||||
old = reg['parent_records'][reg['plan']['imported_parents']['D1']['role']]
|
||||
new = complete['parents'][performance]
|
||||
old_delta, new_delta = (_npz(x['after_overlay']['overlay_file']) for x in (old, new))
|
||||
checks['natural_fullcycle_after_delta_exact'] = set(old_delta) == set(new_delta) and all(B.bit_equal(v, new_delta[k]) for k, v in old_delta.items())
|
||||
checks['natural_fullcycle_U_receipt_exact'] = same_json(read(Path(old['update_dir']) / 'update-receipt.json'), read(Path(new['update_dir']) / 'update-receipt.json'))
|
||||
lineage = _lineage(reg, complete, verified, records)
|
||||
checks.update({name: result['numerical_exact'] for name, result in comparisons.items()})
|
||||
checks['D1_conditional_queue_exact'] = pending['D1']['conditional_ref_request_queue_exact'] and pending['D1']['reference_queue_and_ref_coverage_complete']
|
||||
checks['mechanical_conditional_queue_exact'] = pending['mechanical']['conditional_ref_request_queue_exact'] and pending['mechanical']['reference_queue_and_ref_coverage_complete']
|
||||
checks['actual_idle_and_probe_lineage'] = lineage['pass_all']
|
||||
exact, coverage, status = outcome(checks, pending)
|
||||
require(len(records) == 23 and sum(r['steps'] for r in records.values()) == 125200, 'Actual full-call/tick inventory differs')
|
||||
verify_pins(used_pins)
|
||||
for name, item in verified.items():
|
||||
require(tree(item['output']) == item['output_inventory'], 'Audited outputs changed')
|
||||
require(digest(complete_path) == complete_sha, 'Execution receipt changed')
|
||||
result = dict(schema='conditioning-execution-numerical-audit-v1', complete=True, status=status,
|
||||
pass_all=exact and coverage, numerical_exact=exact, registration_sha256=reg_sha,
|
||||
execution_complete_sha256=digest(complete_path), checks=checks, failed_checks=[k for k, v in checks.items() if not v],
|
||||
comparisons=comparisons, updates=updates, pending_edge_audits=pending, idle_probe_lineage=lineage,
|
||||
actual_new_brain_calls=len(records), actual_new_brain_ticks=sum(r['steps'] for r in records.values()),
|
||||
actual_processes=len(verified), actual_CPU_processes=sum(r['kind'] in ('update', 'validate_cpu') for r in verified.values()),
|
||||
actual_GPU_sampler_processes=sum(r['kind'] == 'sample' for r in verified.values()), all_actual_runs_finite=True,
|
||||
process_evidence={name: dict(kind=v['kind'], process_sha256=digest(v['paths']['process']), worker_sha256=digest(v['paths']['worker']),
|
||||
job_sha256=digest(v['paths']['job']), output_files=len(v['output_inventory']), recorded_exit_code=0) for name, v in verified.items()},
|
||||
observed_scope='Sparse events, complete final state/queues; full reference-only histories; authenticated recorded process evidence',
|
||||
light_intermediate_states_observed=False, AP_D1_changed_edge_coverage_is_not_required=True,
|
||||
historical_integrity_after_checked_here=False, sealed_here=False, brain_executed_here=False,
|
||||
U_recomputed_here=False, learning_pass_claimed=False, full_retention_experiment=False, candidate_generated=False)
|
||||
if save_report:
|
||||
save(EXP / 'audit/numerical-comparison.json', result)
|
||||
return result
|
||||
finally:
|
||||
for record in [*records.values(), *imports.values()]:
|
||||
B.close_record(record)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--registration-sha256', required=True)
|
||||
args = parser.parse_args()
|
||||
result = audit(args.registration_sha256)
|
||||
print(json.dumps({k: result[k] for k in ('complete', 'status', 'pass_all', 'actual_new_brain_calls', 'actual_processes')}), flush=True)
|
||||
@@ -0,0 +1,371 @@
|
||||
"""Pure CPU comparison of live-boundary and saved/restored diagnostics.
|
||||
|
||||
Array APIs require caller-authenticated records and immutable original graph /
|
||||
delta arrays. They do NOT authenticate registrations, process receipts or disk
|
||||
seals. load_record reads existing bytes without writing; its scope tags are not
|
||||
authority. No GPU, learning, membrane replay or physiological inference.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
from types import ModuleType
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
||||
PINS = {
|
||||
'engineering_compare.py': '5a2403f11bc08d65a9d242ac2cf9686b850e0c3680d65659f785e9b6b50c0238',
|
||||
'engineering_queue_audit.py': '6ddaec52f2a0b5d0c528d51230d372fe2344160aef5eccea6a95b6c5e61a574e',
|
||||
}
|
||||
AUTHORITY_FIELDS = {'schema', 'boundary_id', 'registration_sha256', 'transition', 'diagnostic_mode', 'input_policy',
|
||||
'case', 'parent', 'global_tick_offset', 'overlay_before', 'overlay_after',
|
||||
'expected_effective_weight_before_sha256', 'expected_effective_weight_after_sha256', 'update',
|
||||
'cpu_validation', 'source_files', 'frozen_inputs'}
|
||||
|
||||
|
||||
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(filename, expected):
|
||||
path = Path(__file__).resolve().parent.parent / 'olfactory-conditioning-lab-v1' / filename
|
||||
raw = path.read_bytes()
|
||||
if hashlib.sha256(raw).hexdigest() != expected:
|
||||
raise ValueError('Frozen pure helper source differs: ' + filename)
|
||||
module = ModuleType('conditioning_boundary_' + filename[:-3])
|
||||
module.__file__ = str(path)
|
||||
exec(compile(raw, str(path), 'exec'), module.__dict__)
|
||||
return module
|
||||
|
||||
|
||||
C = _load('engineering_compare.py', PINS['engineering_compare.py'])
|
||||
require, bit_equal = C.require, C.bit_equal
|
||||
|
||||
|
||||
def _raw(a):
|
||||
h = hashlib.sha256()
|
||||
for start in range(0, len(a), 1 << 18):
|
||||
h.update(np.ascontiguousarray(a[start:start+(1 << 18)], dtype=a.dtype.newbyteorder('<')).tobytes())
|
||||
return h.hexdigest()
|
||||
|
||||
|
||||
def load_record(directory, *, kind):
|
||||
"""Read actual inherited schemas; never disguise oracle as fixed-weight.
|
||||
|
||||
No external SHA pin is accepted or inferred here. The caller independently
|
||||
verifies the complete oracle/new/old checkpoint seal before this reader.
|
||||
"""
|
||||
require(kind in ('oracle', 'updated', 'parent'), 'Explicit record kind required')
|
||||
record = C.load_run(directory)
|
||||
try:
|
||||
summary = record['summary']
|
||||
if kind == 'oracle':
|
||||
require(summary.get('diagnostic_live_boundary') is True and summary.get('within_trial_weight_updates') is True and
|
||||
summary.get('production_backend') is False and summary.get('restored_from_checkpoint') is False,
|
||||
'Not a declared live-boundary diagnostic')
|
||||
record['boundary_snapshot'] = C._npz(Path(directory)/'boundary-snapshot.npz',
|
||||
('v','g','ref','counts','spike_ring','apl_state','apl_pending'))
|
||||
record['boundary_report'] = C._json(Path(directory)/'boundary-comparison.json')
|
||||
record['oracle_provenance'] = C._json(Path(directory)/'oracle-provenance.json')
|
||||
else:
|
||||
require(summary.get('within_trial_weight_updates') is False, 'Checkpoint segment updated during run')
|
||||
if kind == 'updated':
|
||||
require(summary.get('updated_boundary_schema') == 'conditioning-updated-boundary-v1' and
|
||||
summary.get('checkpoint_continuation_used') is True, 'Not an updated checkpoint segment')
|
||||
record['manifest_sha256'] = _digest(Path(directory)/'checkpoint-manifest.json')
|
||||
record['read_scope'] = kind
|
||||
return record
|
||||
except BaseException:
|
||||
C.close_run(record)
|
||||
raise
|
||||
|
||||
|
||||
def close_record(record):
|
||||
C.close_run(record)
|
||||
|
||||
|
||||
def _checks():
|
||||
checks = {}
|
||||
def check(name, okay):
|
||||
checks[name] = bool(okay)
|
||||
return checks, check
|
||||
|
||||
|
||||
def _complete(record):
|
||||
C.validate_run(record)
|
||||
s=record.get('summary',{})
|
||||
require(s.get('complete') is True and s.get('pass_all') is True and s.get('all_finite') is True and
|
||||
type(s.get('steps')) is int and s['steps']==record['steps']==s.get('completed_ticks') and
|
||||
type(s.get('nodes')) is int and s['nodes']==len(record['state']['v']) and
|
||||
s.get('precision')=='float64' and s.get('apl_precision')=='float32' and s.get('apl_delay_steps')==18,
|
||||
'Record summary is incomplete or has wrong numerical scope')
|
||||
|
||||
|
||||
def _canonical(value):
|
||||
return json.dumps(value,sort_keys=True,separators=(',',':'),ensure_ascii=False,allow_nan=False).encode('utf-8')
|
||||
|
||||
|
||||
def _paired_authorities(pair, oracle_sha, child_sha, child_mode):
|
||||
"""Bind actual raw JSON bytes and compare canonical content, not self hashes.
|
||||
|
||||
File SHA and canonical SHA are intentionally distinct. Only diagnostic_mode
|
||||
and boundary_id may differ; every other byte of canonical JSON must agree.
|
||||
"""
|
||||
require(type(pair) in (tuple,list) and len(pair)==2 and all(type(raw)is bytes for raw in pair),
|
||||
'paired_authorities must be the two original raw JSON byte strings')
|
||||
def unique(items):
|
||||
result={}
|
||||
for key,value in items:
|
||||
require(key not in result,'Duplicate authority JSON key: '+key);result[key]=value
|
||||
return result
|
||||
values=[json.loads(raw.decode('utf-8'),object_pairs_hook=unique,
|
||||
parse_constant=lambda value:(_ for _ in ()).throw(ValueError('Nonfinite authority JSON'))) for raw in pair]
|
||||
for value in values:
|
||||
require(type(value)is dict and set(value)==AUTHORITY_FIELDS and value.get('schema')=='conditioning-updated-boundary-v1',
|
||||
'Paired authority must use the exact boundary schema')
|
||||
require(type(value['boundary_id'])is str and bool(value['boundary_id']) and value['boundary_id'].strip()==value['boundary_id'],
|
||||
'Invalid paired boundary ID')
|
||||
hashes=[hashlib.sha256(raw).hexdigest() for raw in pair]
|
||||
allowed={'diagnostic_mode','boundary_id'}
|
||||
normalized=[{k:v for k,v in value.items() if k not in allowed} for value in values]
|
||||
differences=[key for key in sorted(AUTHORITY_FIELDS-allowed) if _canonical(values[0][key])!=_canonical(values[1][key])]
|
||||
checks=dict(actual_raw_file_SHA_bound=hashes==[oracle_sha,child_sha],
|
||||
explicit_modes=values[0]['diagnostic_mode']=='reference' and values[1]['diagnostic_mode']==child_mode,
|
||||
only_two_allowed_fields_differ=_canonical(normalized[0])==_canonical(normalized[1]))
|
||||
return dict(pass_all=all(checks.values()),checks=checks,raw_sha256=hashes,
|
||||
canonical_sha256=[hashlib.sha256(_canonical(value)).hexdigest() for value in values],
|
||||
common_content_canonical_sha256=[hashlib.sha256(_canonical(value)).hexdigest() for value in normalized],
|
||||
allowed_differences=sorted(allowed),disallowed_different_fields=differences,
|
||||
actual_disk_or_registration_authority_verified_here=False)
|
||||
|
||||
|
||||
def compare_boundary(oracle, continuation, *, parent, expected_before_sha256, expected_after_sha256, paired_authorities=None):
|
||||
"""Compare full oracle prefix/suffix against an authenticated parent/child.
|
||||
|
||||
Both reference and light children are supported. A light child's absent
|
||||
intermediate traces/hashes are explicitly unobserved, never called exact.
|
||||
No nonvacuity gate is invented here; changed-edge coverage is separate.
|
||||
"""
|
||||
for record in (oracle, continuation, parent): _complete(record)
|
||||
require(C._sha(expected_before_sha256) and C._sha(expected_after_sha256), 'External expected weight identities required')
|
||||
require(C._sha(parent.get('manifest_sha256')), 'Caller-authenticated parent manifest identity required')
|
||||
require(parent['global_tick_offset'] == oracle['global_tick_offset'] == 0, 'Need original fresh parent/live oracle')
|
||||
cut, steps = parent['steps'], continuation['steps']
|
||||
require(continuation['global_tick_offset'] == cut and oracle['steps'] == cut+steps, 'Wrong boundary/duration')
|
||||
n = len(parent['state']['v'])
|
||||
require(len(oracle['state']['v']) == len(continuation['state']['v']) == n, 'Population differs')
|
||||
require(oracle.get('traces') and oracle.get('state_hashes') is not None and oracle.get('queues') is not None,
|
||||
'Live oracle must retain full reference diagnostics')
|
||||
os, cs, ps = oracle['summary'], continuation['summary'], parent['summary']
|
||||
require(cs.get('diagnostic_mode') in ('reference','light'), 'Child recording mode is undeclared')
|
||||
reference = cs['diagnostic_mode'] == 'reference'
|
||||
if reference:
|
||||
require(continuation.get('traces') and continuation.get('state_hashes') is not None and continuation.get('queues') is not None,
|
||||
'Reference child diagnostics missing')
|
||||
else:
|
||||
require(not continuation.get('traces') and continuation.get('state_hashes') is None and continuation.get('queues') is None,
|
||||
'Light scope must not manufacture intermediate histories')
|
||||
if ps.get('diagnostic_mode')=='reference':
|
||||
require(parent.get('traces') and parent.get('state_hashes') is not None and parent.get('queues') is not None,
|
||||
'Reference parent diagnostics missing')
|
||||
checks, check = _checks()
|
||||
check('oracle.explicit_live_scope', os.get('diagnostic_mode') == 'reference' and
|
||||
os.get('diagnostic_live_boundary') is True and os.get('within_trial_weight_updates') is True and
|
||||
os.get('explicit_weight_switches') == 1 and type(os.get('explicit_weight_switches')) is int and
|
||||
os.get('boundary_tick') == cut and os.get('restored_from_checkpoint') is False and os.get('production_backend') is False)
|
||||
check('child.explicit_updated_scope', cs.get('within_trial_weight_updates') is False and
|
||||
cs.get('checkpoint_continuation_used') is True and cs.get('updated_boundary_schema') == 'conditioning-updated-boundary-v1' and
|
||||
cs.get('parent_checkpoint_manifest_sha256') == parent['manifest_sha256'] and
|
||||
cs.get('global_next_tick') == cut+steps and cs.get('boundary_transition') == 'epoch_update')
|
||||
check('weights.before', ps.get('effective_weights_raw_sha256') == os.get('initial_effective_weights_raw_sha256') == expected_before_sha256)
|
||||
check('weights.after', cs.get('effective_weights_raw_sha256') == os.get('effective_weights_raw_sha256') == expected_after_sha256)
|
||||
ot, on = oracle['state']['step'], oracle['state']['neuron_idx']
|
||||
split = int(np.searchsorted(ot,cut))
|
||||
check('prefix.events.tick',bit_equal(ot[:split],parent['state']['step']))
|
||||
check('prefix.events.neuron_idx',bit_equal(on[:split],parent['state']['neuron_idx']))
|
||||
check('prefix.counts',np.array_equal(np.bincount(on[:split],minlength=n),parent['state']['counts']))
|
||||
check('suffix.events.absolute_tick',np.array_equal(continuation['state']['step'].astype(np.int64)+cut,ot[split:].astype(np.int64)))
|
||||
check('suffix.events.neuron_idx',bit_equal(continuation['state']['neuron_idx'],on[split:]))
|
||||
check('suffix.segment_counts',np.array_equal(continuation['state']['counts'],np.bincount(on[split:],minlength=n)))
|
||||
check('prefix_plus_suffix.total_counts',np.array_equal(parent['state']['counts'].astype(np.int64)+continuation['state']['counts'],oracle['state']['counts']))
|
||||
for name in ('v','g','ref'):check('final.'+name,bit_equal(continuation['state'][name],oracle['state'][name]))
|
||||
check('final.phase_normalized_spike_ring',bit_equal(C.normalized_ring(continuation['terminal']),C.normalized_ring(oracle['terminal'])))
|
||||
for name in ('apl_pending','apl_state'):check('final.'+name,bit_equal(continuation['terminal'][name],oracle['terminal'][name]))
|
||||
snapshot = oracle.get('boundary_snapshot')
|
||||
require(type(snapshot) is dict and set(snapshot) == {'v','g','ref','counts','spike_ring','apl_state','apl_pending'}, 'Missing live boundary snapshot')
|
||||
for name in ('v','g','ref','counts'):check('boundary.live_parent.'+name,bit_equal(snapshot[name],parent['state'][name]))
|
||||
for name in ('spike_ring','apl_state','apl_pending'):check('boundary.live_parent.'+name,bit_equal(snapshot[name],parent['terminal'][name]))
|
||||
report, provenance = oracle.get('boundary_report'), oracle.get('oracle_provenance')
|
||||
require(type(report) is dict and type(provenance) is dict, 'Missing explicit oracle provenance/report')
|
||||
paired=None
|
||||
authority_matches=(C._sha(cs.get('boundary_authority_sha256')) and
|
||||
provenance.get('authority_sha256')==cs['boundary_authority_sha256'])
|
||||
if paired_authorities is not None:
|
||||
paired=_paired_authorities(paired_authorities,provenance.get('authority_sha256'),
|
||||
cs.get('boundary_authority_sha256'),cs['diagnostic_mode'])
|
||||
authority_matches=paired['pass_all']
|
||||
check('oracle.boundary_metadata',report.get('complete') is True and report.get('boundary_tick') == cut and
|
||||
report.get('parent_checkpoint_manifest_sha256') == parent['manifest_sha256'] and report.get('restore_called') is False and
|
||||
report.get('initial_state_replaced') is False and report.get('queues_replaced') is False and report.get('existing_weights_replaced_once') is True and
|
||||
report.get('before_effective_sha256') == expected_before_sha256 and report.get('after_effective_sha256') == expected_after_sha256)
|
||||
check('oracle.authority_matches_child',provenance.get('schema') == 'conditioning-live-boundary-oracle-v1' and
|
||||
provenance.get('complete') is True and provenance.get('restore_called') is False and
|
||||
provenance.get('prefix_sparse_events_exact') is True and provenance.get('learning_pass_claimed') is False and
|
||||
authority_matches)
|
||||
for label,record,start,stop in (('prefix',parent,0,cut),('suffix',continuation,cut,cut+steps)):
|
||||
req=oracle['requests'];lo,hi=np.searchsorted(req[:,0],(start,stop))
|
||||
actual=record['requests'].copy();actual[:,0]+=start
|
||||
check(label+'.requests_all_five_fields',bit_equal(actual,req[lo:hi]))
|
||||
if record.get('traces'):
|
||||
for name in C.TRACE_FILES:check(label+'.trace.'+name,bit_equal(record['traces'][name],oracle['traces'][name][start:stop]))
|
||||
if record.get('state_hashes') is not None:
|
||||
check(label+'.state_hashes',all(all(row[key]==oracle['state_hashes'][start+t][key] for key in C.HASH_FIELDS)
|
||||
for t,row in enumerate(record['state_hashes'])))
|
||||
if record.get('queues') is not None:
|
||||
check(label+'.queue_order_acceptance',all(all(row[key]==oracle['queues'][start+t][key] for key in C.QUEUE_FIELDS)
|
||||
for t,row in enumerate(record['queues'])))
|
||||
consume=min(steps,18)
|
||||
if reference:check('boundary.applied_parent_APL',bit_equal(continuation['traces']['applied'][:consume],parent['terminal']['apl_pending'][:consume]))
|
||||
if steps<18:check('boundary.unconsumed_parent_APL',bit_equal(continuation['terminal']['apl_pending'][:18-steps],parent['terminal']['apl_pending'][steps:]))
|
||||
if steps<19:check('boundary.unwritten_parent_spike_slots',bit_equal(continuation['terminal']['spike_ring'][steps:],C.normalized_ring(parent['terminal'])[steps:]))
|
||||
exact=all(checks.values())
|
||||
return dict(schema='conditioning-live-vs-restored-comparison-v1',pass_all=exact,numerical_exact=exact,
|
||||
status='EXACT-RECORDED-BOUNDARY-SCOPE-NOT-LEARNING' if exact else 'FAIL-BOUNDARY-NUMERICAL',checks=checks,
|
||||
failed_checks=[k for k,v in checks.items() if not v],boundary_tick=cut,suffix_steps=steps,neurons=n,
|
||||
child_mode=cs['diagnostic_mode'],suffix_reference_diagnostics_compared=reference,
|
||||
paired_authority_audit=paired,
|
||||
light_intermediate_states_observed=False,light_per_tick_identity_claimed=False,
|
||||
queue_joint_hash_compared=False,queue_joint_hash_exclusion='Local tick headers differ; independent audit checks each actual header',
|
||||
changed_candidate_pending_arrival_coverage_verified=False,external_file_authority_verified_here=False,
|
||||
independent_membrane_replay_performed=False,learning_pass_claimed=False,candidate_generated=False)
|
||||
|
||||
|
||||
def _effective_hash(base, apl, rows, values):
|
||||
h=hashlib.sha256()
|
||||
for start in range(0,len(base),1<<18):
|
||||
stop=min(start+(1<<18),len(base));a=np.array(base[start:stop],copy=True)
|
||||
a[apl[start:stop]]=np.float64(0)
|
||||
lo,hi=np.searchsorted(rows,(start,stop));a[rows[lo:hi]-start]=values[lo:hi]
|
||||
h.update(np.ascontiguousarray(a,dtype='<f8').tobytes())
|
||||
return h.hexdigest()
|
||||
|
||||
|
||||
def _candidates(ptr,src,dst,edge_id,base,apl,ids,before,after,Q):
|
||||
n,e=Q._graph(ptr,dst,edge_id,base)
|
||||
require(isinstance(src,np.ndarray) and src.dtype==np.int32 and src.shape==(e,), 'Invalid actual CSR source array')
|
||||
require(isinstance(apl,np.ndarray) and apl.dtype==np.bool_ and apl.shape==(e,), 'Invalid fast APL mask')
|
||||
for start in range(0,e,1<<18):
|
||||
stop=min(start+(1<<18),e)
|
||||
expected=np.searchsorted(ptr[1:],np.arange(start,stop,dtype=np.int64),side='right')
|
||||
require(np.array_equal(src[start:stop],expected),'Source array disagrees with original CSR ordering')
|
||||
require(isinstance(ids,np.ndarray) and ids.dtype==np.int64 and ids.ndim==1 and len(ids)>0 and
|
||||
np.all(ids>=0) and np.all(ids[1:]>ids[:-1]),'Candidate IDs must preserve canonical sorted unique order')
|
||||
for name,a in (('before',before),('after',after)):
|
||||
require(isinstance(a,np.ndarray) and a.dtype==np.float32 and a.shape==ids.shape and
|
||||
np.isfinite(a).all() and np.all(a<=0),'Invalid f32 mV delta '+name)
|
||||
require(np.all(after<=before),'This diagnostic admits only existing depression, not potentiation')
|
||||
rows=np.searchsorted(edge_id,ids)
|
||||
require(np.all(rows<e) and np.array_equal(edge_id[rows],ids),'Candidate missing from actual graph')
|
||||
require(not np.any(apl[rows]) and np.all(base[rows]>0),'Candidate overlaps APL or has nonpositive original weight')
|
||||
values=[]
|
||||
for delta in (before,after):
|
||||
a=base[rows].copy();nz=delta!=np.float32(0)
|
||||
a[nz]=np.add(a[nz],np.multiply(delta[nz].astype(np.float64),np.float64(.001)))
|
||||
require(np.isfinite(a).all() and np.all(a>0),'Effective candidate weight changed sign/nonfinite')
|
||||
values.append(a)
|
||||
return n,e,rows,values[0],values[1]
|
||||
|
||||
|
||||
def audit_changed_pending(parent,child,*,ptr,src,dst,edge_id,base_weights,apl_mask,
|
||||
candidate_edge_id,delta_before,delta_after,input_pins):
|
||||
"""Conditional ref/request/CSR audit plus a changed-edge crossing witness.
|
||||
|
||||
Post-threshold ref=22 precedes arrivals; requests use prior ref<=1. Every
|
||||
real edge remains in source/CSR order, including rejected/zero weights.
|
||||
Witnesses require an actual numeric effective-weight change and accepted
|
||||
arrival emitted before cut and arriving within the child. This is not a
|
||||
unique-cause claim and does not independently predict membrane spikes.
|
||||
"""
|
||||
require(type(input_pins)is dict and input_pins and all(type(k)is str and C._sha(v) for k,v in input_pins.items()),'Caller input anchors required')
|
||||
Q=_load('engineering_queue_audit.py',PINS['engineering_queue_audit.py'])
|
||||
for record in (parent,child):_complete(record)
|
||||
n,e,rows,before,after=_candidates(ptr,src,dst,edge_id,base_weights,apl_mask,candidate_edge_id,delta_before,delta_after,Q)
|
||||
require(parent['global_tick_offset']==0 and child['global_tick_offset']==parent['steps'],'Fresh parent / exact child boundary required')
|
||||
require(len(parent['state']['v'])==len(child['state']['v'])==n,'Record/graph population mismatch')
|
||||
require(all(type(record['summary'].get('edges')) is int and record['summary']['edges']==e for record in (parent,child)),
|
||||
'Record/graph edge count differs')
|
||||
cut,total=parent['steps'],parent['steps']+child['steps']
|
||||
require(total<=np.iinfo(np.int32).max,'Diagnostic clock exceeds exact int32 event range')
|
||||
before_sha=_effective_hash(base_weights,apl_mask,rows,before);after_sha=_effective_hash(base_weights,apl_mask,rows,after)
|
||||
require(parent['summary'].get('effective_weights_raw_sha256')==before_sha and
|
||||
child['summary'].get('effective_weights_raw_sha256')==after_sha,'Delta/base arithmetic mismatches actual runtime effective SHA')
|
||||
changed=(before.view(np.uint64)!=after.view(np.uint64)) & (before!=after)
|
||||
changed_rows=rows[changed];changed_ids=candidate_edge_id[changed]
|
||||
effective=base_weights.copy();effective[apl_mask]=np.float64(0);effective[rows]=after
|
||||
tick=np.concatenate((parent['state']['step'],child['state']['step']+np.int32(cut)))
|
||||
node=np.concatenate((parent['state']['neuron_idx'],child['state']['neuron_idx']))
|
||||
request=np.concatenate((parent['requests'],child['requests']+np.array([cut,0,0,0,0],np.int64)))
|
||||
ref=np.zeros(n,np.int32);differences=[];difference_count=0
|
||||
def check(ok,field,t):
|
||||
nonlocal difference_count
|
||||
if not ok:
|
||||
difference_count+=1
|
||||
if len(differences)<60:differences.append(dict(field=field,global_tick=t))
|
||||
coverage=dict(changed_candidate_crossing_arrivals=0,accepted_changed_candidate_crossing_arrivals=0,
|
||||
rejected_changed_candidate_crossing_arrivals=0,first_witness=None)
|
||||
full=all(record.get('queues') is not None and record.get('state_hashes') is not None for record in (parent,child))
|
||||
for t in range(total):
|
||||
record,local=(parent,t) if t<cut else (child,t-cut)
|
||||
rlo,rhi=np.searchsorted(request[:,0],(t,t+1));requested=request[rlo:rhi,1]
|
||||
accepted=ref[requested]<=1
|
||||
expected=request[rlo:rhi].copy();expected[:,2]=1;expected[:,3]=accepted;expected[:,4]=~accepted
|
||||
check(bit_equal(request[rlo:rhi],expected),'request.acceptance',t)
|
||||
np.maximum(ref-np.int32(1),np.int32(0),out=ref)
|
||||
lo,hi=np.searchsorted(tick,(t,t+1));fired=node[lo:hi]
|
||||
check(np.all(ref[fired]==0),'spike_during_refractory',t)
|
||||
check(np.isin(requested[accepted],fired,assume_unique=True).all(),'accepted_request_without_spike',t)
|
||||
ref[fired]=22
|
||||
lo,hi=np.searchsorted(tick,(t-18,t-17));sources=node[lo:hi] if t>=18 else node[:0]
|
||||
qrows,_,_=Q._queue(t,local,sources,ref,ptr,dst,edge_id,effective,[])
|
||||
expected_queue=qrows[0] if t<cut else qrows[1]
|
||||
if record.get('queues') is not None:
|
||||
check(record['queues'][local]==expected_queue,'source_ordered_queue_all_fields',t)
|
||||
if record.get('state_hashes') is not None:
|
||||
check(record['state_hashes'][local]['ref_sha256']==_raw(ref),'ref_hash',t)
|
||||
if local==record['steps']-1:check(bit_equal(record['state']['ref'],ref),'final_ref',t)
|
||||
if t-18<cut<=t and t<total:
|
||||
for source in sources:
|
||||
lo,hi=np.searchsorted(changed_rows,(ptr[source],ptr[source+1]))
|
||||
for at in range(int(lo),int(hi)):
|
||||
row=int(changed_rows[at]);target=int(dst[row]);accepted_edge=ref[target]==0
|
||||
coverage['changed_candidate_crossing_arrivals']+=1
|
||||
coverage['accepted_changed_candidate_crossing_arrivals' if accepted_edge else 'rejected_changed_candidate_crossing_arrivals']+=1
|
||||
if accepted_edge and coverage['first_witness'] is None:
|
||||
original=int(np.searchsorted(rows,row))
|
||||
coverage['first_witness']=dict(global_edge_id=int(changed_ids[at]),csr_row=row,
|
||||
source_neuron_idx=int(source),target_neuron_idx=target,source_spike_global_tick=t-18,
|
||||
arrival_global_tick=t,arrival_child_local_tick=t-cut,post_threshold_target_ref=0,accepted=True,
|
||||
before_weight_SI_volt=float(before[original]),after_weight_SI_volt=float(after[original]),
|
||||
before_weight_f64_le_hex=np.asarray(before[original],dtype='<f8').tobytes().hex(),
|
||||
after_weight_f64_le_hex=np.asarray(after[original],dtype='<f8').tobytes().hex(),
|
||||
delta_before_f32_mv_hex=np.asarray(delta_before[original],dtype='<f4').tobytes().hex(),
|
||||
delta_after_f32_mv_hex=np.asarray(delta_after[original],dtype='<f4').tobytes().hex(),
|
||||
unique_cause_or_necessity_claim=False)
|
||||
exact=difference_count==0;witness=coverage['first_witness'] is not None;passed=exact and full and witness
|
||||
return dict(schema='conditioning-changed-pending-edge-audit-v1',pass_all=passed,
|
||||
status='FAIL-QUEUE-REF-REQUEST' if not exact else ('PASS-CHANGED-PENDING-EDGE-SCOPE' if passed else 'INCOMPLETE-CHANGED-EDGE-COVERAGE'),
|
||||
conditional_ref_request_queue_exact=exact,reference_queue_and_ref_coverage_complete=full,
|
||||
accepted_changed_edge_witness_verified=passed,difference_count=difference_count,differences=differences,
|
||||
differences_truncated=difference_count>len(differences),coverage=coverage,neurons=n,edges=e,boundary_tick=cut,
|
||||
changed_delta_bit_count=int(np.count_nonzero(delta_before.view(np.uint32)!=delta_after.view(np.uint32))),
|
||||
changed_effective_numeric_count=int(changed.sum()),before_effective_sha256=before_sha,after_effective_sha256=after_sha,
|
||||
supplied_input_pins=dict(input_pins),array_raw_sha256={key:_raw(a) for key,a in dict(ptr=ptr,src=src,dst=dst,edge_id=edge_id,
|
||||
base_weights=base_weights,apl_mask=apl_mask,candidate_edge_id=candidate_edge_id,delta_before=delta_before,delta_after=delta_after).items()},
|
||||
delay_steps=18,refractory_steps=22,actual_membrane_dynamics_independently_replayed=False,
|
||||
observed_spikes_condition_the_audit=True,external_file_authority_verified_here=False,learning_pass_claimed=False)
|
||||
@@ -0,0 +1,219 @@
|
||||
"""Diagnostic live-boundary oracle, NOT a production/learned brain backend.
|
||||
|
||||
Re-execute a fresh parent's exact inputs/old overlay, without calling restore.
|
||||
At the declared epoch boundary compare live state to the sealed parent, replace
|
||||
only existing candidate weights with base+delta-after, and continue the original
|
||||
reference loop. One whitelisted hook is independently removable from its AST.
|
||||
The diagnostic has an explicit within-run boundary switch; old C must NOT load
|
||||
its output as an unchanged-weight checkpoint.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import ast
|
||||
import copy
|
||||
import hashlib
|
||||
import importlib.util
|
||||
import json
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
import numpy as np
|
||||
|
||||
LAB=Path(__file__).resolve().parent.parent/'olfactory-conditioning-lab-v1'
|
||||
C_SHA='0b8e8e0a6a23a079dc62a88355ce355d53b3ae22f6665519a8f6aef2dcfc5aba'
|
||||
HOOK="if tick == _oracle.boundary_tick:\n _oracle.switch(tick, weights, v, g, ref, counts, ring, apl_ring, apl, out_dir)"
|
||||
|
||||
|
||||
def require(ok,message):
|
||||
if not ok:raise ValueError(message)
|
||||
|
||||
|
||||
def digest(path):
|
||||
h=hashlib.sha256()
|
||||
with Path(path).open('rb') as stream:
|
||||
for b in iter(lambda:stream.read(8<<20),b''):h.update(b)
|
||||
return h.hexdigest()
|
||||
|
||||
|
||||
def load(name,path,sha):
|
||||
raw=Path(path).read_bytes()
|
||||
require(hashlib.sha256(raw).hexdigest()==sha and name not in sys.modules,'Unverified oracle source/module binding')
|
||||
spec=importlib.util.spec_from_file_location(name,path);module=importlib.util.module_from_spec(spec)
|
||||
sys.modules[name]=module;exec(compile(raw,str(path),'exec'),module.__dict__)
|
||||
return module
|
||||
|
||||
|
||||
def frozen():
|
||||
return load('_conditioning_live_oracle_C',LAB/'runtime_continuation.py',C_SHA)
|
||||
|
||||
|
||||
def derive_oracle(c,source_bytes):
|
||||
tree,inherited=c.R.derive_ast(source_bytes,'reference');before=copy.deepcopy(tree)
|
||||
loops=[n for n in ast.walk(tree) if isinstance(n,ast.For) and isinstance(n.target,ast.Name) and n.target.id=='tick']
|
||||
require(len(loops)==1,'Unique frozen timestep loop required')
|
||||
loops[0].body.insert(0,ast.parse(HOOK).body[0]);tree=ast.fix_missing_locations(tree)
|
||||
rollback=copy.deepcopy(tree)
|
||||
matches=[n for n in ast.walk(rollback) if isinstance(n,ast.For) and isinstance(n.target,ast.Name) and n.target.id=='tick']
|
||||
require(ast.unparse(matches[0].body[0])==HOOK,'Oracle hook changed')
|
||||
del matches[0].body[0]
|
||||
require(c.R._dump(rollback)==c.R._dump(before),'Unlisted oracle mathematical AST edit')
|
||||
return tree,dict(base=inherited,explicit_boundary_hook=HOOK,full_AST_rollback_identical=True,
|
||||
frozen_within_epoch_math_unchanged=True,restore_called=False,
|
||||
diagnostic_live_weight_switch=True,production_backend=False,
|
||||
ast_sha256=hashlib.sha256(c.R._dump(tree).encode()).hexdigest())
|
||||
|
||||
|
||||
def expected_candidate_values(base_si,edge_ids,after_delta):
|
||||
"""Base+f32-mV delta with the frozen separate f64 multiply/add contract."""
|
||||
require(base_si.dtype==np.float64 and base_si.ndim==1 and edge_ids.dtype==np.int64 and edge_ids.ndim==1 and
|
||||
after_delta.dtype==np.float32 and after_delta.shape==edge_ids.shape,'Wrong candidate bridge dtype/shape')
|
||||
require(np.all((edge_ids>=0)&(edge_ids<len(base_si))) and np.all(edge_ids[1:]>edge_ids[:-1]),'Invalid existing edge IDs')
|
||||
require(np.isfinite(after_delta).all() and np.all(after_delta<=0),'Invalid depression delta')
|
||||
result=base_si[edge_ids].copy();nonzero=after_delta!=np.float32(0)
|
||||
result[nonzero]=np.add(result[nonzero],np.multiply(after_delta[nonzero].astype(np.float64),np.float64(.001)))
|
||||
require(np.isfinite(result).all() and np.all(result>0),'Candidate sign changed')
|
||||
return result
|
||||
|
||||
|
||||
def boundary_arrays(parent,tick,v,g,ref,counts,ring,apl_ring,apl_state):
|
||||
require(type(tick)is int and tick==parent['steps']==parent['global_next_tick'] and parent['fresh'] is True,
|
||||
'Oracle needs the exact fresh-parent boundary')
|
||||
arrays=dict(v=v,g=g,ref=ref,counts=counts,spike_ring=ring,apl_state=apl_state,
|
||||
apl_pending=np.concatenate((apl_ring[tick%18:],apl_ring[:tick%18]),axis=0))
|
||||
expected={**{k:parent['state'][k] for k in ('v','g','ref','counts')},
|
||||
**{k:parent['terminal'][k] for k in ('spike_ring','apl_state','apl_pending')}}
|
||||
checks={k:(a.dtype==expected[k].dtype and a.shape==expected[k].shape and a.tobytes()==expected[k].tobytes())
|
||||
for k,a in arrays.items()}
|
||||
require(all(checks.values()),'Live prefix differs from sealed parent: '+str([k for k,v in checks.items() if not v]))
|
||||
return arrays,checks
|
||||
|
||||
|
||||
def runtime_class(c):
|
||||
r=c.R
|
||||
class Oracle(r._Runtime):
|
||||
def __init__(self,*args,boundary,**kwargs):
|
||||
super().__init__(*args,**kwargs);self.boundary=boundary;self.parent=boundary['parent']
|
||||
self.boundary_tick=self.parent['steps'];self.switches=0
|
||||
|
||||
def tensor_sha(self,value):
|
||||
h=hashlib.sha256()
|
||||
for start in range(0,value.numel(),1<<20):h.update(value[start:start+(1<<20)].cpu().numpy().astype('<f8',copy=False).tobytes())
|
||||
return h.hexdigest()
|
||||
|
||||
def install(self,weights,graph,apl_mask,upload,out_dir,inherited,device):
|
||||
require(self.installations==0 and len(graph['nodes'])==166700 and len(graph['edge_id'])==25582938 and
|
||||
int(apl_mask.sum())==5845,'Only one intact frozen fullgraph installation')
|
||||
prior=self.helper.map_installation(graph['weights'],graph['edge_id'],apl_mask,self.plan)
|
||||
following=self.helper.map_installation(graph['weights'],graph['edge_id'],apl_mask,self.boundary['after_plan'])
|
||||
require(prior['missing_candidate_count']==following['missing_candidate_count']==0,'Incomplete candidate mapping')
|
||||
if len(prior['rows']):
|
||||
idx=upload(prior['rows'],self.torch.int64)
|
||||
change=upload(self.plan['plastic_delta_mv'][self.plan['plastic_delta_mv']!=np.float32(0)],self.torch.float64)*.001
|
||||
weights[idx]=weights[idx]+change
|
||||
require(self.helper.bit_equal(weights[idx].cpu().numpy(),prior['expected_si']),'Initial SI bridge mismatch')
|
||||
base_sha,before_sha=self.helper.expected_hashes(graph['weights'],apl_mask,prior)
|
||||
_,after_sha=self.helper.expected_hashes(graph['weights'],apl_mask,following)
|
||||
require(before_sha==self.parent['summary']['effective_weights_raw_sha256'] and self.tensor_sha(weights)==before_sha,
|
||||
'Oracle before weights differ from parent')
|
||||
auth=self.boundary['value']
|
||||
require(before_sha==auth['expected_effective_weight_before_sha256'] and after_sha==auth['expected_effective_weight_after_sha256'],
|
||||
'External expected weights differ')
|
||||
mask=self.plan['edge_id'];require(np.array_equal(graph['edge_id'][mask],mask),'Noncanonical candidate positions')
|
||||
expected=expected_candidate_values(graph['weights'],mask,self.boundary['after_plan']['plastic_delta_mv'])
|
||||
nz=self.boundary['after_plan']['plastic_delta_mv']!=np.float32(0)
|
||||
require(self.helper.bit_equal(expected[nz],following['expected_si']),'Independent after bridge differs')
|
||||
self.rows_gpu=upload(mask,self.torch.int64);self.after_gpu=upload(expected,self.torch.float64)
|
||||
self.before_sha,self.after_sha=before_sha,after_sha;self.effective_sha=before_sha
|
||||
self.observer=r.FiniteObserver(self.torch,device);self.installations=1
|
||||
for role,target in (('before_overlay','overlay-before-input.npz'),('before_manifest','overlay-before-manifest.json'),
|
||||
('after_overlay','overlay-after-input.npz'),('after_manifest','overlay-after-manifest.json')):
|
||||
source=self.boundary['paths'][role];r._copy_input(source,out_dir/target,r.digest(source))
|
||||
r._save(out_dir/'overlay-audit.json',dict(schema='conditioning-live-oracle-overlay-v1',complete=True,
|
||||
base_weights_raw_sha256=base_sha,initial_effective_weights_raw_sha256=before_sha,
|
||||
planned_final_effective_weights_raw_sha256=after_sha,weights_updated_during_run=True,
|
||||
one_explicit_epoch_boundary=True,existing_candidates_only=True,production_checkpoint=False))
|
||||
|
||||
def switch(self,tick,weights,v,g,ref,counts,ring,apl_ring,apl,out_dir):
|
||||
require(self.installations==1 and self.switches==0 and tick==self.boundary_tick,'Wrong/repeated boundary switch')
|
||||
arrays,checks=boundary_arrays(self.parent,tick,*[a.cpu().numpy().copy() for a in
|
||||
(v,g,ref,counts,ring,apl_ring,apl.state)])
|
||||
require(self.tensor_sha(weights)==self.before_sha,'Weights changed before authorized boundary')
|
||||
# Replacement from ORIGINAL base; never increment by delta-after again.
|
||||
weights[self.rows_gpu]=self.after_gpu
|
||||
require(self.tensor_sha(weights)==self.after_sha,'Live boundary after-weight mismatch')
|
||||
self.effective_sha=self.after_sha;self.switches=1
|
||||
with (out_dir/'boundary-snapshot.npz').open('xb') as f:np.savez_compressed(f,**arrays)
|
||||
r._save(out_dir/'boundary-comparison.json',dict(complete=True,boundary_tick=tick,checks=checks,
|
||||
parent_checkpoint_manifest_sha256=self.parent['manifest_sha256'],restore_called=False,
|
||||
initial_state_replaced=False,queues_replaced=False,existing_weights_replaced_once=True,
|
||||
before_effective_sha256=self.before_sha,after_effective_sha256=self.after_sha))
|
||||
|
||||
def finish(self,*args,**kwargs):
|
||||
require(self.switches==1,'Expected diagnostic boundary did not execute')
|
||||
return super().finish(*args,**kwargs)
|
||||
|
||||
def summary(self,value):
|
||||
result=super().summary(value)
|
||||
result.update(within_trial_weight_updates=True,diagnostic_live_boundary=True,
|
||||
boundary_tick=self.boundary_tick,explicit_weight_switches=self.switches,
|
||||
effective_weights_raw_sha256=self.after_sha,initial_effective_weights_raw_sha256=self.before_sha,
|
||||
restored_from_checkpoint=False,production_backend=False,
|
||||
pass_all_scope='One diagnostic live boundary and finite integrity; no learning/equivalence claim')
|
||||
return result
|
||||
return Oracle
|
||||
|
||||
|
||||
def run(authority_file,authority_sha,updated_source_sha,oracle_case,spec_sha,requests_sha,out_dir,build_root):
|
||||
require(sys.dont_write_bytecode,'Use Python -B')
|
||||
d=load('_conditioning_live_oracle_updated',Path(__file__).with_name('updated_continuation.py'),updated_source_sha)
|
||||
boundary=d.validate_authority(authority_file,authority_sha)
|
||||
c=d.C;r=c.R;parent=boundary['parent'];paths=boundary['paths'];value=boundary['value']
|
||||
require(value['transition']=='epoch_update' and parent['fresh'] is True,'Live oracle supports one verified fresh epoch update only')
|
||||
case=Path(oracle_case).resolve(strict=True)
|
||||
require(digest(case/'spec.json')==spec_sha and digest(case/'requests.npz')==requests_sha,'Combined oracle input differs from external pins')
|
||||
spec=r._read_json(case/'spec.json');previous=c._parent_spec(parent);suffix=boundary['spec']
|
||||
require(spec.get('within_trial_weight_updates') is True and spec.get('diagnostic_boundary_tick')==parent['steps'],
|
||||
'Oracle must explicitly declare its one within-run boundary')
|
||||
r.validate_spec({**spec,'within_trial_weight_updates':False},case)
|
||||
require(spec['steps']==parent['steps']+suffix['steps'],'Combined oracle clock differs')
|
||||
for key in ('dt_ms','model','apl','apl_delay_steps','graph_dir','apl_bundle_dir','coefficients_path'):
|
||||
require(spec[key]==previous[key]==suffix[key],'Oracle changes frozen input/dynamics: '+key)
|
||||
def requests(path):
|
||||
with np.load(path,allow_pickle=False) as f:
|
||||
require(set(f.files)=={'tick','neuron_idx'},'Invalid request archive')
|
||||
a={k:f[k].copy() for k in f.files}
|
||||
require(all(v.dtype==np.int32 and v.ndim==1 for v in a.values()),'Invalid request dtype')
|
||||
return a
|
||||
epoch=r._read_json(paths['epoch_authority'])
|
||||
old=requests(epoch['files']['requests']['path']);new=requests(paths['requests']);combined=requests(case/'requests.npz')
|
||||
expected={'tick':np.concatenate((old['tick'],new['tick']+parent['steps'])),
|
||||
'neuron_idx':np.concatenate((old['neuron_idx'],new['neuron_idx']))}
|
||||
require(all(np.array_equal(combined[k],expected[k]) for k in expected),'Oracle prefix/suffix requests are not exact')
|
||||
protected={*parent['ancestry_directories'],*[Path(p).parent for p in boundary['pins']]}
|
||||
case,out,build=r.execution_paths(case,out_dir,build_root,protected)
|
||||
inputs={**boundary['pins'],str(case/'spec.json'):spec_sha,str(case/'requests.npz'):requests_sha,str(Path(__file__).resolve()):digest(__file__)}
|
||||
aj_dir=Path(boundary['before_meta']['aj_model_dir']).resolve()
|
||||
r._load('timing_queue',aj_dir/'timing_queue.py',r.PINS['apl-timing-lab-v1/timing_queue.py'])
|
||||
aj=r._load('conditioning_live_oracle_AJ',aj_dir/'gpu_timing.py',r.AJ_SHA)
|
||||
runtime=runtime_class(c)('reference',spec,boundary['helper'],boundary['before_plan'],boundary['before_meta'],
|
||||
inputs,aj.torch,paths['before_overlay'],paths['before_manifest'],boundary=boundary)
|
||||
tree,audit=derive_oracle(c,Path(aj.__file__).read_bytes())
|
||||
namespace=dict(aj.__dict__);namespace.update(__name__=__name__+'.derived',__file__=str(Path(__file__).resolve()),
|
||||
_runtime=runtime,_oracle=runtime,write_json=runtime.write_json)
|
||||
exec(compile(tree,str(Path(__file__).resolve())+'::live-boundary-AST','exec'),namespace)
|
||||
inherited=namespace['run_gpu'](case,out,build)
|
||||
require(runtime.finished and runtime.switches==1 and inherited['complete'],'Incomplete live-boundary oracle')
|
||||
with np.load(out/'state.npz',allow_pickle=False) as state:
|
||||
prefix=state['step']<parent['steps']
|
||||
require(np.array_equal(state['step'][prefix],parent['state']['step']) and
|
||||
np.array_equal(state['neuron_idx'][prefix],parent['state']['neuron_idx']),'Oracle prefix events differ from actual parent')
|
||||
require(all(digest(p)==sha for p,sha in inputs.items()),'Oracle source/input drift')
|
||||
c.load_checkpoint(parent['directory'],parent['manifest_sha256'])
|
||||
summary=r._read_json(out/'summary.json');require(summary==runtime.summary(inherited),'Oracle summary mismatch')
|
||||
r._save(out/'oracle-provenance.json',dict(schema='conditioning-live-boundary-oracle-v1',complete=True,
|
||||
source_sha256=digest(__file__),updated_source_sha256=updated_source_sha,authority_sha256=authority_sha,
|
||||
input_sha256=inputs,ast=audit,restore_called=False,old_globals_patched=False,
|
||||
prefix_sparse_events_exact=True,production_checkpoint=False,learning_pass_claimed=False))
|
||||
files={p.relative_to(out).as_posix():digest(p) for p in out.rglob('*') if p.is_file()}
|
||||
r._save(out/'oracle-manifest.json',dict(schema='conditioning-live-oracle-files-v1',complete=True,files_sha256=files))
|
||||
return summary
|
||||
@@ -0,0 +1,249 @@
|
||||
"""Pure, finite boundary-validation proposal; no disk, sampling, runtime or GPU.
|
||||
|
||||
Pins and claimed array identities are descriptors, NOT verification of disk bytes,
|
||||
biological membership, registration or execution permission. The coordinator must
|
||||
authenticate them and safely materialize cases. This is not acquisition, a full
|
||||
retention experiment, or evidence of learning. No thresholds/model knobs change.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from copy import deepcopy
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import PurePosixPath
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
||||
SCHEMA = 'conditioning-boundary-plan-v1-draft'
|
||||
MASTER = 20260930
|
||||
BLOCK = 'physiological__PAM15__reinforce_A__rep01'
|
||||
COMPARTMENT = "y5B'2a"
|
||||
N, CANDIDATES = 166700, 14232
|
||||
AP_ROOT = '/data/digital-drosophila/experiments/phase4ap-conditioning-interface-v2'
|
||||
TEMPLATE_PAYLOAD_SHA256 = 'fbd892d6b05e93747f70b70051b36b43922b773633de9ad64bb00af6206a51e1'
|
||||
SOURCE_PINS = {
|
||||
'conditioning-interface-v2/coordinator.py': '7862fed19bcf3878f42783af6286574371a2d58c66719c99cabab8f18ec99a34',
|
||||
'conditioning-interface-v2/isolated_workers.py': 'e47651a8ea99d7c44115107ff6b5dc71312183609ae11c891db65bb21ed61e30',
|
||||
'conditioning-interface-v2/test_coordinator.py': 'ffd2951c2bf23ea1a4a8d598fa1be9f07f71e60ad28fe5a06eed17537946d900',
|
||||
'conditioning-interface-v2/test_isolated_workers.py': 'd72fcc10f32a1284fa49491cb19f29e83b37b472051985e2fda56799c14a2e60',
|
||||
'conditioning-interface-v2/PROTOCOL.md': '2a1c553e6be87df02db8d357f00eb88c9dea3c9b75b6ef670dd55f45492d7518',
|
||||
'olfactory-conditioning-lab-v1/seed_registry.py': '0da033b132095ec3087b5d9f64e53c2e391fa50ab0b7653b31296eeb84799b7e',
|
||||
'olfactory-conditioning-lab-v1/trial_plan.py': '6fed3f494d075339a7e5b001d43b2598640b189e038952fbd4d41200bacac587',
|
||||
}
|
||||
AP_ANCHORS = {
|
||||
'protocol/preregistered.json': '02a03b536a9f14196ad4b92fa9565b592732c6c863e72eeaee89b3b0ea8ed37d',
|
||||
'manifest.json': 'a40e433541a6c02f7ad95622e96646da9a90a93e4e43cb3abfde3846b2554f00',
|
||||
'audit/final-status.json': '26de8371867d55253358a4be698de896445712e49e6eee8d99ce852fd0bf43ab',
|
||||
'cases/D1--reference--epoch-001/spec.json': 'f0b8eddd78a2dc0e1d6fcae07489dcb24aa3c5bb14326367fa32cfdf960739ba',
|
||||
}
|
||||
PARENT_PINS = {
|
||||
'D1': 'df328eddff4c735e08fae377bbd7c4cd0df288de60c6ebd34965e28c369fc084',
|
||||
'D0': '6511e794c4f0f9929e81bd7363ad2314f0e44d9f95882883ab3644cf2b1a6fd9',
|
||||
'frozen': 'ebebf86480d6fe9facb4f08689783a1b78143f4794fa11694d68dd9efb806373',
|
||||
}
|
||||
STALE_INPUT_KEYS = frozenset(('CS_window', 'cs_input_seed', 'cs_input_seed_bits', 'expected_CS_requests',
|
||||
'mode', 'odor_id', 'odor_name', 'rate_sum_hz', 'source_panel_row', 'source_panel_split',
|
||||
'target_count', 'seed_scope', 'outer_arm', 'outer_epoch_id'))
|
||||
CASE_CHANGED_KEYS = frozenset(('name', 'steps', 'max_steps', 'duration_ms', 'budget_root',
|
||||
'output_budget_bytes', 'outer_protocol', 'within_trial_weight_updates'))
|
||||
CASE_ADDED_KEYS = frozenset(('boundary_diagnostic', 'input_policy', 'scientific_learning_claimed',
|
||||
'diagnostic_boundary_tick', 'evaluation_stream_id', 'cue', 'probe_fork_discard'))
|
||||
|
||||
|
||||
def _require(ok, message):
|
||||
if not ok:
|
||||
raise ValueError(message)
|
||||
|
||||
|
||||
def _canonical(value):
|
||||
return json.dumps(value, sort_keys=True, separators=(',', ':'), ensure_ascii=False, allow_nan=False)
|
||||
|
||||
|
||||
def _sha(value):
|
||||
return hashlib.sha256(_canonical(value).encode('utf-8')).hexdigest()
|
||||
|
||||
|
||||
def evaluation_seeds():
|
||||
"""Exact frozen seed/stream rules; derive only, never draw random numbers."""
|
||||
result = {}
|
||||
for cue, odor in (('A', '4-ethylphenol'), ('B', '3-hexanone')):
|
||||
key = [BLOCK, 'evaluation', 'CS', cue, '00', 'base-probe']
|
||||
digest = _sha(['phase4an-seed-registry-v1', MASTER, 'evaluation', key])
|
||||
result[cue] = dict(cue=cue, odor=odor, master=MASTER, split='evaluation', key=key,
|
||||
seed=int(digest[:16], 16) & ((1 << 63)-1), seed_bits=63, derivation_sha256=digest,
|
||||
stream_id='evaluation:' + _sha(['phase4an-trial-plan-v1-draft', 'stream-id', MASTER, 'evaluation', key]))
|
||||
return result
|
||||
|
||||
|
||||
def build_plan():
|
||||
"""Fixed proposal; all future hashes and identity checks remain external."""
|
||||
calls = []
|
||||
|
||||
def add(name, runner, mode, steps, parent, offset, overlay, policy='empty_idle', **extra):
|
||||
group = name
|
||||
if '--updated--' in name or '--old-C--' in name:
|
||||
arm = name.split('--')[0]
|
||||
group = ('mechanical' if arm == 'mechanical' else 'AP-'+arm)+'-suffix'
|
||||
calls.append(dict(call_id=name, runner=runner, diagnostic_mode=mode, steps=steps,
|
||||
case_group=group,
|
||||
parent=parent, global_tick_offset=offset, global_next_tick=offset+steps,
|
||||
overlay_after_role=overlay, input_policy=policy, scientific_learning_claimed=False, **extra))
|
||||
|
||||
imports = {arm: dict(role=f'AP.{arm}.reference.epoch001',
|
||||
checkpoint_manifest=AP_ROOT+f'/runs/{arm}--reference--epoch-001/checkpoint-manifest.json',
|
||||
sha256=pin, steps_already_executed=1200) for arm, pin in PARENT_PINS.items()}
|
||||
for arm in ('D1', 'D0', 'frozen'):
|
||||
parent = imports[arm]['role']
|
||||
after = parent+'.original_E.after'
|
||||
for mode in ('reference', 'light'):
|
||||
add(f'{arm}--updated--{mode}', 'updated_continuation', mode, 1000, parent, 1200, after,
|
||||
transition='epoch_update', overlay_before_role=parent+'.recorded_overlay')
|
||||
if arm == 'D1':
|
||||
add('D1--live-oracle', 'boundary_oracle', 'reference', 2200, None, 0, after,
|
||||
policy='replay_AP_prefix_then_empty_idle', prefix_replay_parent=parent,
|
||||
overlay_before_role=parent+'.recorded_overlay', diagnostic_boundary_tick=1200,
|
||||
within_trial_weight_updates=True, restore_used=False)
|
||||
else:
|
||||
add(f'{arm}--old-C--reference', 'runtime_continuation', 'reference', 1000, parent,
|
||||
1200, parent+'.recorded_overlay', transition='same_weight')
|
||||
add('performance--natural-light-fresh', 'runtime_light', 'light', 1200, None, 0,
|
||||
'AP.D1.reference.epoch001.recorded_overlay', policy='replay_AP_D1_epoch001_input',
|
||||
input_replay_source='AP.D1.reference.epoch001', performance_training_cycle=True,
|
||||
regression_against='AP.D1.reference.epoch001', new_learning=False, input_sampled=False)
|
||||
add('performance--evaluation-A-light-fresh', 'fresh_probe', 'light', 1200, None, 0,
|
||||
'AP.initial_overlay', policy='externally_pinned_CS_probe', cue='A',
|
||||
performance_probe_cycle=True, probe_fork_discard=True, neural_reset=True,
|
||||
US=False, plastic_update=False, feedback_to_idle=False,
|
||||
evaluation_stream_id=evaluation_seeds()['A']['stream_id'])
|
||||
add('mechanical--fresh-parent', 'runtime_light', 'reference', 1200, None, 0,
|
||||
'AP.initial_overlay', policy='synthetic_one_KC_plus_four_PAM15_at_tick1199',
|
||||
inherited_learned_delta=False, olfactory_input=False)
|
||||
for mode in ('reference', 'light'):
|
||||
add(f'mechanical--updated--{mode}', 'updated_continuation', mode, 1000,
|
||||
'mechanical--fresh-parent', 1200, 'mechanical.original_E.after', transition='epoch_update',
|
||||
overlay_before_role='AP.initial_overlay')
|
||||
add('mechanical--live-oracle', 'boundary_oracle', 'reference', 2200, None, 0,
|
||||
'mechanical.original_E.after', policy='replay_mechanical_prefix_then_empty_idle',
|
||||
prefix_replay_parent='mechanical--fresh-parent', overlay_before_role='AP.initial_overlay',
|
||||
diagnostic_boundary_tick=1200, within_trial_weight_updates=True, restore_used=False)
|
||||
parent = imports['D1']['role']
|
||||
after = parent+'.original_E.after'
|
||||
add('D1--idle--1s', 'updated_continuation', 'light', 10000, parent, 1200, after,
|
||||
transition='epoch_update', overlay_before_role=parent+'.recorded_overlay')
|
||||
add('D1--idle--9s', 'updated_continuation', 'light', 90000, 'D1--idle--1s', 11200, after,
|
||||
transition='idle', overlay_before_role=after)
|
||||
for label, branch, offset, transition in (('t0', parent, 1200, 'epoch_update'),
|
||||
('t1', 'D1--idle--1s', 11200, 'idle'), ('t10', 'D1--idle--9s', 101200, 'idle')):
|
||||
for cue in ('A', 'B'):
|
||||
add(f'D1--probe--{label}--{cue}', 'updated_continuation', 'light', 1200, branch, offset,
|
||||
after, policy='externally_pinned_CS_probe', transition=transition, cue=cue,
|
||||
overlay_before_role=parent+'.recorded_overlay' if label == 't0' else after,
|
||||
probe_fork_discard=True, feedback_to_idle=False, neural_reset=False, US=False,
|
||||
plastic_update=False, evaluation_stream_id=evaluation_seeds()[cue]['stream_id'])
|
||||
zero_root = '/data/digital-drosophila/experiments/'
|
||||
return dict(schema=SCHEMA, status='DRAFT-NOT-REGISTERED', calls=calls, imported_parents=imports,
|
||||
initial_overlay=dict(role='AP.initial_overlay', registration_field='initial_overlay',
|
||||
overlay_file=dict(path=zero_root+'phase4am-wholebrain-plastic-interface/overlays/zero.npz',
|
||||
sha256='0b219eab09c30dc3af31fef7e6395a9bec1234090abbb72db096da833fed82c5'),
|
||||
overlay_manifest=dict(path=zero_root+'phase4an-engineering-validation/overlays/zero.json',
|
||||
sha256='11b668978f3070dad26d99d9310bebefa0731fa0d4e361e8dc0ef02a213277c2')),
|
||||
source_sha256=deepcopy(SOURCE_PINS), AP_anchors_sha256=deepcopy(AP_ANCHORS),
|
||||
AP_source_commit='0bcce983324ecfe1c75826a23e94ff932ad5e883', evaluation_streams=evaluation_seeds(),
|
||||
mechanical_update=dict(coordinator='original_E', update='original_U', parent='mechanical--fresh-parent',
|
||||
before_overlay_role='AP.initial_overlay', steps=1200, us_tick=1199, d_command=1.0,
|
||||
frozen=False, compartment=COMPARTMENT, trace_backend='torch'),
|
||||
performance_update=dict(coordinator='original_E', update='original_U', parent='performance--natural-light-fresh',
|
||||
before_overlay_role='AP.D1.reference.epoch001.recorded_overlay', steps=1200, us_tick=900,
|
||||
d_command=1.0, frozen=False, compartment=COMPARTMENT, trace_backend='torch',
|
||||
required_regression=['all_events', 'final_state', 'delta_after'],
|
||||
timing_scope='before_brain_spawn_through_original_E_exit_and_independent_CPU_validation'),
|
||||
cpu_children=[*[dict(role='verify_AP_original_E', parent=imports[a]['role']) for a in imports],
|
||||
dict(role='performance_original_E'), dict(role='verify_performance_original_E'),
|
||||
dict(role='mechanical_original_E'), dict(role='verify_mechanical_original_E')],
|
||||
sampler_child=dict(role='evaluation_sampler', execution='GPU_private_generator',
|
||||
uniform_batch_calls=2, cues=['A', 'B']),
|
||||
counts=dict(new_brain_calls=23, new_brain_ticks=125200, distinct_case_groups=17, imported_brain_calls=3,
|
||||
imported_brain_ticks=3600, covered_brain_ticks=128800, cpu_children=7, gpu_sampler_children=1, total_children=31,
|
||||
new_CS_uniform_batch_calls=2, raw_uniform_draw_count=None, raw_draw_count_known=False),
|
||||
budget_proposal=dict(output_bytes=4*2**30, free_reserve_bytes=10*2**30,
|
||||
child_timeout_seconds=1800, workflow_timeout_seconds=7200, approved=False,
|
||||
on_limit='stop_and_report_incomplete; never_shorten_trial_or_change_gate'),
|
||||
protected_contract=dict(brain_model='unchanged', APL='unchanged', delay='unchanged',
|
||||
sign='unchanged', threshold='unchanged', eta='unchanged', candidate_mask_count=14232),
|
||||
external_requirements=['authenticate_all_source_protocol_checkpoint_and_overlay_bytes',
|
||||
'authenticate_candidate_endpoints_KC_membership_and_exact_PAM15_membership',
|
||||
'bind_original_E_outputs_and_CPU_recomputation_receipts',
|
||||
'register_new_sources_cases_inputs_budget_and_exact_execution_authority',
|
||||
'sample_two_evaluation_CS_batches_with_pinned_real_generator_then_reuse_at_three_times'],
|
||||
brain_executed=False, inputs_sampled=False, acquisition_executed=False,
|
||||
full_retention_experiment=False, scientific_learning_claimed=False,
|
||||
external_identity_verified_here=False, execution_authorized=False)
|
||||
|
||||
|
||||
def validate_plan(plan):
|
||||
_require(_canonical(plan) == _canonical(build_plan()), 'Plan differs from fixed independent reconstruction')
|
||||
return True
|
||||
|
||||
|
||||
def derive_case_spec(template, call_id, *, budget_root):
|
||||
"""Narrow derivation of the actual AP D1 template; no claimed file checking."""
|
||||
_require(_sha(template) == TEMPLATE_PAYLOAD_SHA256, 'Not the pinned AP template payload')
|
||||
_require(type(budget_root) is str, 'Output root must be an absolute POSIX string')
|
||||
root = PurePosixPath(budget_root)
|
||||
_require(root.is_absolute() and '..' not in root.parts and
|
||||
str(root) not in ('/', AP_ROOT) and PurePosixPath(AP_ROOT) not in root.parents and
|
||||
root not in PurePosixPath(AP_ROOT).parents, 'Use a distinct absolute non-ancestor output root')
|
||||
call = next((c for c in build_plan()['calls'] if c['call_id'] == call_id), None)
|
||||
_require(call is not None, 'Unknown fixed call')
|
||||
result = {k: deepcopy(v) for k, v in template.items() if k not in STALE_INPUT_KEYS}
|
||||
result.update(name=call['case_group'], steps=call['steps'], max_steps=call['steps'], duration_ms=call['steps']*.1,
|
||||
budget_root=str(root), output_budget_bytes=4*2**30, outer_protocol=SCHEMA,
|
||||
within_trial_weight_updates=call.get('within_trial_weight_updates', False),
|
||||
boundary_diagnostic=call['case_group'], input_policy=call['input_policy'], scientific_learning_claimed=False)
|
||||
if 'diagnostic_boundary_tick' in call:
|
||||
result['diagnostic_boundary_tick'] = call['diagnostic_boundary_tick']
|
||||
if 'cue' in call:
|
||||
stream = evaluation_seeds()[call['cue']]
|
||||
result.update(mode='physiological', cue=call['cue'], odor_name=stream['odor'], CS_window=[0, 1000],
|
||||
cs_input_seed=stream['seed'], cs_input_seed_bits=63, evaluation_stream_id=stream['stream_id'],
|
||||
probe_fork_discard=True, seed_scope='reset seed unchanged; full63 evaluation CS seed used by external sampler')
|
||||
return result
|
||||
|
||||
|
||||
def mechanical_requests(candidate_map, pam15_ids, *, identity_binding):
|
||||
"""Caller authenticates mapping/DAN membership; only array schema checked here.
|
||||
|
||||
Select minimum canonical KC index, never based on outcome. Returned requests
|
||||
are synthetic deterministic force requests, not odor samples or accepted spikes.
|
||||
"""
|
||||
roles = {'edge_id', 'source_neuron_idx', 'target_neuron_idx', 'target_compartment_verbatim'}
|
||||
_require(type(candidate_map) is dict and set(candidate_map) == roles, 'Exact candidate map schema required')
|
||||
for key, array in candidate_map.items():
|
||||
_require(isinstance(array, np.ndarray) and array.shape == (CANDIDATES,), 'Full candidate arrays required')
|
||||
expected = np.int64 if key == 'edge_id' else np.int32
|
||||
_require(array.dtype.kind == 'U' if key == 'target_compartment_verbatim' else array.dtype == expected,
|
||||
'Candidate dtype changed')
|
||||
edge = candidate_map['edge_id']
|
||||
_require(np.all(edge >= 0) and np.all(edge < 25582938) and np.all(edge[1:] > edge[:-1]), 'Canonical edge order required')
|
||||
for key in ('source_neuron_idx', 'target_neuron_idx'):
|
||||
_require(np.all((candidate_map[key] >= 0) & (candidate_map[key] < N)), 'Neuron index out of range')
|
||||
_require(isinstance(pam15_ids, np.ndarray) and pam15_ids.dtype == np.int32 and pam15_ids.shape == (4,)
|
||||
and np.all((pam15_ids >= 0) & (pam15_ids < N)) and np.all(pam15_ids[1:] > pam15_ids[:-1]),
|
||||
'Four canonical sorted unique int32 PAM15 indices required')
|
||||
_require(type(identity_binding) is dict and set(identity_binding) == {'candidate_map_sha256', 'pam15_membership_sha256'}
|
||||
and all(type(v) is str and len(v) == 64 and all(c in '0123456789abcdef' for c in v)
|
||||
for v in identity_binding.values()), 'External identity digest descriptors required')
|
||||
sources = candidate_map['source_neuron_idx'][candidate_map['target_compartment_verbatim'] == COMPARTMENT]
|
||||
_require(len(sources) > 0, 'No exact y5B\'2a candidate rows')
|
||||
selected = int(sources.min())
|
||||
_require(selected not in pam15_ids, 'KC/DAN identity overlap')
|
||||
node = np.sort(np.concatenate((np.array([selected], dtype=np.int32), pam15_ids)))
|
||||
audit = dict(selected_KC_source_neuron_idx=selected, PAM15_neuron_idx=pam15_ids.tolist(), tick=1199,
|
||||
request_count=5, compartment=COMPARTMENT, identity_binding=deepcopy(identity_binding),
|
||||
selection='minimum canonical source_neuron_idx among exact compartment candidate rows',
|
||||
input_arrays={k: dict(dtype=a.dtype.str, shape=list(a.shape), raw_c_order_sha256=
|
||||
hashlib.sha256(a.tobytes(order='C')).hexdigest()) for k, a in candidate_map.items()},
|
||||
external_identity_verified_here=False, olfactory_input=False, sampled=False, accepted_spikes_verified=False,
|
||||
before_overlay_role='AP.initial_overlay', inherited_learned_delta=False, scientific_learning_claimed=False)
|
||||
return dict(tick=np.full(5, 1199, dtype=np.int32), neuron_idx=node), audit
|
||||
@@ -0,0 +1,75 @@
|
||||
"""Exactly two registered evaluation-input batches; no brain, US or learning."""
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import time
|
||||
|
||||
import numpy as np
|
||||
|
||||
import boundary_plan as PLAN
|
||||
import execution_authority as A
|
||||
|
||||
MODEL=Path(__file__).resolve().parent
|
||||
LAB=MODEL.parent/'olfactory-conditioning-lab-v1'
|
||||
PINS={
|
||||
'conditioning_inputs.py':'19382e066e450140bb653a3661f980ffe7cc62f412020ef57df0b6e6b3cbb8ba',
|
||||
'conditioning_preflight_inputs.py':'846d2141b472f18b1bb728eed4aa33876896d4b33dece364787c81204f62995f',
|
||||
'evaluation_plan.py':'991c813ff3322b230947f302b12b04ec382c3b632817f94b698101e4b17efa7d',
|
||||
'trial_plan.py':'6fed3f494d075339a7e5b001d43b2598640b189e038952fbd4d41200bacac587',
|
||||
'seed_registry.py':'0da033b132095ec3087b5d9f64e53c2e391fa50ab0b7653b31296eeb84799b7e',
|
||||
}
|
||||
|
||||
|
||||
def save(path,value):
|
||||
with Path(path).open('x',encoding='utf-8') as f:json.dump(value,f,sort_keys=True,indent=2,allow_nan=False)
|
||||
|
||||
|
||||
def run(authority_file,authority_sha,out_dir):
|
||||
A.require(sys.dont_write_bytecode and A.digest(authority_file)==authority_sha,'Use -B with external registration pin')
|
||||
reg=A.read(authority_file)
|
||||
A.require(reg['schema']=='conditioning-execution-registration-v1','Wrong input generation authority')
|
||||
PLAN.validate_plan(reg['plan'])
|
||||
for path,sha in {**reg['source_sha256'],**reg['input_sha256'],**reg['prepared_file_sha256']}.items():
|
||||
A.require(A.pin(path)['sha256']==sha,'Sampler source/input drift')
|
||||
for name,sha in PINS.items():
|
||||
A.require(A.digest(LAB/name)==sha and reg['input_sha256'].get(str(LAB/name))==sha,'Unpinned frozen input dependency: '+name)
|
||||
A.require(not any(name in sys.modules for name in ('conditioning_inputs','conditioning_preflight_inputs','evaluation_plan')),
|
||||
'Sampler needs fresh scientific imports')
|
||||
sys.path.insert(0,str(LAB))
|
||||
import conditioning_preflight_inputs as I
|
||||
import conditioning_inputs as CI
|
||||
import evaluation_plan as EP
|
||||
rates=I.load_rate_tables('/data/digital-drosophila')
|
||||
full=reg['original_full_plan'];A.require(A.digest(full['path'])==full['sha256'],'Full seed/trial plan changed')
|
||||
streams=EP._streams(A.read(full['path']))
|
||||
exp=Path(authority_file).parent.parent;out=Path(out_dir)
|
||||
A.require(not out.exists() and out.parent.is_dir() and out.is_relative_to(exp),'Exclusive new sampler output required')
|
||||
out.mkdir();rows=[]
|
||||
for cue in ('A','B'):
|
||||
declared=reg['plan']['evaluation_streams'][cue];actual=streams[(PLAN.BLOCK,cue)]
|
||||
for field in ('seed','seed_bits','stream_id','derivation_sha256'):
|
||||
A.require(declared[field]==actual[field],'Evaluation semantic stream differs')
|
||||
A.require(declared['key']==actual['semantic_key'] and actual['split']=='evaluation','Evaluation stream provenance differs')
|
||||
table=rates['tables'][cue]
|
||||
with np.load(exp/f'inputs/static/{cue}-rates.npz',allow_pickle=False) as saved:
|
||||
A.require(all(saved[k].dtype==table[k].dtype and saved[k].shape==table[k].shape and
|
||||
saved[k].tobytes()==table[k].tobytes() for k in ('targets','rates_hz')),'Registered original PN mapping changed')
|
||||
started=time.perf_counter()
|
||||
result=CI.generate_cs_requests(table['targets'],table['rates_hz'],seed=declared['seed'],steps=1200,
|
||||
cs_start_tick=0,cs_stop_tick=1000,device='cuda:0',max_uniform_draws=1200*len(table['targets']))
|
||||
with (out/f'{cue}-requests.npz').open('xb') as f:np.savez_compressed(f,**result['requests'])
|
||||
save(out/f'{cue}-sampler.json',result['audit'])
|
||||
rows.append(dict(cue=cue,stream=actual,requests=len(result['requests']['tick']),US_requests=0,
|
||||
uniform_draws=1200*len(table['targets']),wall_seconds=time.perf_counter()-started,
|
||||
saved_requests_sha256=A.digest(out/f'{cue}-requests.npz')))
|
||||
pins={p.name:A.digest(p) for p in out.iterdir() if p.is_file()}
|
||||
summary=dict(schema='conditioning-boundary-sampler-v1',complete=True,registration_sha256=authority_sha,
|
||||
uniform_batch_calls=2,uniform_draws=sum(r['uniform_draws'] for r in rows),rows=rows,files_sha256=pins,
|
||||
brain_executed=False,learning_executed=False,US_added=False,original_rate_mapping_preserved=True,
|
||||
inputs_sampled_once=True,planned_retention_reuse_checkpoints_seconds=[0,1,10],
|
||||
reuse_executed_here=False,seed_search=False,learning_success_claimed=False)
|
||||
save(out/'sampler-receipt.json',summary)
|
||||
return summary
|
||||
@@ -0,0 +1,277 @@
|
||||
"""Read-only actual boundary-cost accounting; never authorizes normal training.
|
||||
|
||||
Only the two registered fresh/light performance cycles are cost samples. Their
|
||||
next serial cycle start is a measured conservative tail-completion upper bound,
|
||||
not an invented postvalidation duration. All current compiled-cache bytes are
|
||||
charged to EACH sample (deliberate overcount); cache reuse is never free by fiat.
|
||||
No normal directory-hashing/finalization policy or reserves are registered yet,
|
||||
so the strict full-suite forecast remains INSUFFICIENT-MEASUREMENTS. This report
|
||||
does not independently re-observe historical OS exits or certify learning.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from copy import deepcopy
|
||||
import hashlib
|
||||
import json
|
||||
import math
|
||||
from pathlib import Path
|
||||
|
||||
import execution_authority as A
|
||||
import execution_budget as B
|
||||
import execution_workflow as F
|
||||
|
||||
|
||||
SCHEMA = 'conditioning-actual-budget-report-v1'
|
||||
TRAIN = 'performance--natural-light-fresh'
|
||||
PROBE = 'performance--evaluation-A-light-fresh'
|
||||
SELECTED = {TRAIN: [('brain',TRAIN),('original_E',TRAIN+'--original-E'),('cpu_validator',TRAIN+'--cpu-verify')],
|
||||
PROBE: [('brain',PROBE)]}
|
||||
POLICY = 'measured-fresh-light-1200-fullgraph-with-original-E-and-CPU-verification-for-training'
|
||||
require = A.require
|
||||
|
||||
|
||||
def _canonical(value):
|
||||
return json.dumps(value,sort_keys=True,separators=(',', ':'),ensure_ascii=False,allow_nan=False)
|
||||
|
||||
|
||||
def _sha(value):
|
||||
return hashlib.sha256(_canonical(value).encode()).hexdigest()
|
||||
|
||||
|
||||
def _same(a,b):
|
||||
return _canonical(a)==_canonical(b)
|
||||
|
||||
|
||||
def _number(value):
|
||||
return type(value) in (int,float) and math.isfinite(value) and value>=0
|
||||
|
||||
|
||||
class Evidence:
|
||||
def __init__(self):
|
||||
self.pins={}
|
||||
self.derived={}
|
||||
|
||||
def pin(self,path,expected=None):
|
||||
if not Path(path).exists():
|
||||
raise FileNotFoundError(2,'Missing measurement evidence',str(path))
|
||||
entry=A.pin(path);p=entry['path'];sha=entry['sha256']
|
||||
require(expected is None or sha==expected,'Evidence bytes changed: '+p)
|
||||
require(p not in self.pins or self.pins[p]==sha,'Conflicting evidence pin: '+p)
|
||||
self.pins[p]=sha
|
||||
return dict(receipt_id=p,sha256=sha)
|
||||
|
||||
def read(self,path,expected=None):
|
||||
self.pin(path,expected)
|
||||
return A.read(path)
|
||||
|
||||
def inventory(self,directory):
|
||||
result=F.tree(directory)
|
||||
for name,row in result.items():self.pin(Path(directory)/name,row['sha256'])
|
||||
return result
|
||||
|
||||
def derived_binding(self,name,value):
|
||||
key='derived:'+name
|
||||
self.derived[key]=deepcopy(value)
|
||||
return dict(receipt_id=key,sha256=_sha(value))
|
||||
|
||||
def authenticated(self):
|
||||
return {**self.pins,**{key:_sha(value) for key,value in self.derived.items()}}
|
||||
|
||||
|
||||
def _parent_process(name,reg,reg_sha,evidence):
|
||||
exp=F.EXP;process_path=exp/'receipts'/f'{name}.process.json'
|
||||
process=evidence.read(process_path)
|
||||
require(process['schema']=='conditioning-execution-process-v1' and process['complete'] is True and
|
||||
process['name']==name and process['registration_sha256']==reg_sha and
|
||||
type(process['exit_code']) is int and process['exit_code']==0 and process['timed_out'] is False,
|
||||
'Unsuccessful/unbound parent process: '+name)
|
||||
jobpath=exp/'jobs'/f'{name}.json';job=evidence.read(jobpath,process['job_sha256'])
|
||||
workerpath=exp/'receipts'/f'{name}.worker.json'
|
||||
worker=evidence.read(workerpath,process['worker_receipt_sha256'])
|
||||
ap=job['kind'] in ('brain','update');script=F.AP_WORKER if ap else F.MODEL/'isolated_execution.py'
|
||||
schema='phase4ap-isolated-worker-receipt-v1' if ap else 'conditioning-isolated-execution-receipt-v1'
|
||||
worker_sha=F.W.AP_SHA if ap else reg['source_sha256'][str(script)]
|
||||
require(worker['schema']==schema and worker['complete'] is True and job['worker_sha256']==worker_sha and
|
||||
all(worker[k]==job[k] for k in ('job_id','kind','registration_sha256','worker_sha256')) and
|
||||
job['job_id']==name and job['kind']==process['kind'] and job['registration_sha256']==reg_sha and
|
||||
worker['job_sha256']==process['job_sha256'] and job['receipt_file']==str(workerpath),
|
||||
'Worker/job/parent receipt identity differs')
|
||||
expected={**job['input_sha256'],str(jobpath):process['job_sha256'],str(script):worker_sha}
|
||||
if ap:expected.update({v['path']:v['sha256'] for v in job['sources'].values()})
|
||||
else:
|
||||
expected[str(F.AP_WORKER)]=F.W.AP_SHA
|
||||
expected.update({str(F.MODEL/n):s for n,s in job['source_sha256'].items()})
|
||||
require(expected.get(str(exp/'protocol/preregistered.json'))==reg_sha and
|
||||
worker['verified_input_sha256' if ap else 'input_sha256']==expected,'Actual input/source closure differs')
|
||||
for path,sha in expected.items():evidence.pin(path,sha)
|
||||
command=process['argv']
|
||||
require(type(command) is list and len(command)>3 and command[1:3]==['-B',str(script)] and
|
||||
command[3:]==(['brain' if job['kind']=='brain' else 'update'] if ap else [])+
|
||||
['--job',str(jobpath),'--job-sha256',process['job_sha256']], 'Observed child command differs')
|
||||
for side in ('stdout','stderr'):evidence.pin(exp/'logs'/f'{name}.{side}.log',process[side+'_sha256'])
|
||||
evidence.pin(str(workerpath)+'.attempt.json',worker['attempt_sha256'])
|
||||
output=Path(job['output_dir'])
|
||||
require(output.is_relative_to(exp) and worker['output_dir']==str(output),'Wrong child output root')
|
||||
inventory=evidence.inventory(output);hashes={k:v['sha256'] for k,v in inventory.items()}
|
||||
require(inventory and hashes==worker['output_files_sha256'] and
|
||||
process['output_bytes']==sum(v['bytes'] for v in inventory.values()) and
|
||||
process['output_inventory_sha256']==hashlib.sha256(json.dumps(hashes,sort_keys=True).encode()).hexdigest(),
|
||||
'Actual complete child output inventory differs')
|
||||
start,exit_,end=(process[k] for k in ('spawn_monotonic','exit_monotonic','validation_end_monotonic'))
|
||||
require(all(_number(v) for v in (start,exit_,end)) and start<exit_<=end and
|
||||
math.isclose(process['child_wall_seconds'],exit_-start,rel_tol=1e-12) and
|
||||
math.isclose(process['end_to_end_seconds'],end-start,rel_tol=1e-12) and
|
||||
math.isclose(process['validation_wall_seconds'],end-exit_,rel_tol=1e-12),'Parent timing layers differ')
|
||||
return dict(process=process,job=job,worker=worker,output_inventory=inventory,
|
||||
binding=evidence.pin(process_path))
|
||||
|
||||
|
||||
def _cycle_files(name,events,evidence):
|
||||
"""Exact newly generated scope of the frozen workflow performance branches."""
|
||||
paths=set()
|
||||
for row in events:
|
||||
job=row['job'];event=job['job_id'];output=Path(job['output_dir'])
|
||||
paths.update(output/key for key in row['output_inventory'])
|
||||
paths.update(F.EXP/f'{directory}/{event}{suffix}' for directory,suffix in
|
||||
(('jobs','.json'),('receipts','.worker.json'),('receipts','.worker.json.attempt.json'),
|
||||
('receipts','.process.json'),('logs','.stdout.log'),('logs','.stderr.log')))
|
||||
brain=events[0]['job'];case=Path(brain['case_dir'])
|
||||
require(case==F.EXP/'cases'/name,'Performance case must be separate, not a continuation/shared case')
|
||||
paths.update(case/n for n in ('spec.json','requests.npz'))
|
||||
if name==TRAIN:paths.add(F.EXP/'authorities'/f'{name}.epoch.json')
|
||||
result={}
|
||||
for path in paths:
|
||||
entry=evidence.pin(path)
|
||||
result[path.relative_to(F.EXP).as_posix()]=dict(sha256=entry['sha256'],bytes=path.stat().st_size)
|
||||
return result
|
||||
|
||||
|
||||
def _collect(reg,reg_sha,evidence):
|
||||
complete=evidence.read(F.EXP/'audit/execution-complete.json')
|
||||
calls=reg['plan']['calls'];ordered=[c['call_id'] for c in calls]
|
||||
require(complete['complete'] is True and complete['registration_sha256']==reg_sha and
|
||||
complete['scientific_learning_pass_claimed'] is False and complete['completed_calls']==ordered,
|
||||
'Actual complete fixed workflow required')
|
||||
names=set(ordered)|{'evaluation-inputs','AP-D1--cpu-verify','AP-D0--cpu-verify','AP-frozen--cpu-verify'}
|
||||
names|={base+suffix for base in (TRAIN,'mechanical--fresh-parent') for suffix in ('--original-E','--cpu-verify')}
|
||||
require(set(complete['processes'])==names and len(names)==reg['plan']['counts']['total_children'],
|
||||
'Actual finite process inventory differs')
|
||||
for name,path in complete['processes'].items():
|
||||
require(Path(path)==F.EXP/'receipts'/f'{name}.process.json','Unexpected process receipt location')
|
||||
processes={name:_parent_process(name,reg,reg_sha,evidence) for name in sorted(names)}
|
||||
attempt=evidence.read(F.EXP/'audit/execution-attempt.json')
|
||||
require(attempt['registration_sha256']==reg_sha and _number(attempt['monotonic_origin']), 'Missing parent clock origin')
|
||||
cycles={name:evidence.read(F.EXP/'receipts'/f'{name}.cycle.json') for name in ordered}
|
||||
for call in calls:
|
||||
cycle=cycles[call['call_id']]
|
||||
require(cycle['complete'] is True and cycle['learning_pass_claimed'] is False and
|
||||
cycle['source_registration_sha256']==reg_sha and _same(cycle['call'],call), 'Cycle/registration binding differs')
|
||||
final_build=evidence.inventory(F.EXP/'extension-build')
|
||||
require(_same(cycles[ordered[-1]]['mutable_build_inventory_after'],final_build), 'Final mutable cache inventory changed')
|
||||
build_bytes=sum(v['bytes'] for v in final_build.values())
|
||||
samples=[];accounts={};contexts=[]
|
||||
for name,roles in SELECTED.items():
|
||||
cycle=cycles[name];next_name=ordered[ordered.index(name)+1];tail_end=cycles[next_name]['start_monotonic']
|
||||
start,end=cycle['start_monotonic'],cycle['end_monotonic']
|
||||
require(all(_number(v) for v in (start,end,tail_end)) and attempt['monotonic_origin']<=start<end<=tail_end and
|
||||
math.isclose(cycle['wall_seconds'],end-start,rel_tol=1e-12),'Missing ordered adjacent-cycle tail bound')
|
||||
rows=[processes[n] for _,n in roles];brain=rows[0];job=brain['job']
|
||||
require(job['kind']=='brain' and job['diagnostic_mode']=='light','Only complete fresh light brain samples')
|
||||
summary=evidence.read(Path(job['output_dir'])/'summary.json')
|
||||
expected=dict(steps=1200,completed_ticks=1200,explicit_steps_executed=1200,max_steps=1200,nodes=B.N,edges=B.E,
|
||||
diagnostic_mode='light',entire_neural_trial_executed=True,within_trial_weight_updates=False,
|
||||
precision='float64',apl_precision='float32')
|
||||
require(all(_same(summary.get(k),v) for k,v in expected.items()) and
|
||||
brain['worker']['result']['complete_fresh_trial'] is True, 'Incomplete/different fresh neural trial')
|
||||
spec=evidence.read(Path(job['case_dir'])/'spec.json')
|
||||
require(spec['dt_ms']==.1 and spec['steps']==1200 and
|
||||
'parent_checkpoint_manifest_sha256' not in spec and 'global_tick_offset' not in spec,
|
||||
'Continuation or changed clock cannot estimate fresh normal costs')
|
||||
if name==TRAIN:
|
||||
epoch=evidence.read(rows[1]['job']['authority_file']);cpu=rows[2]['job']
|
||||
require(rows[1]['job']['kind']=='update' and cpu['kind']=='validate_cpu' and
|
||||
cpu['authority_file']==rows[1]['job']['authority_file'] and cpu['update_dir']==rows[1]['job']['output_dir'] and
|
||||
epoch['checkpoint_dir']==job['output_dir'] and epoch['command']==dict(steps=1200,compartment="y5B'2a",
|
||||
us_tick=900,d_command=1.,frozen=False,trace_backend='torch'), 'Training cycle E/CPU parts differ')
|
||||
else:
|
||||
call=cycle['call']
|
||||
require(call['US'] is False and call['plastic_update'] is False and call['parent'] is None and
|
||||
job['overlay_file']==reg['initial_overlay']['overlay_file'], 'Fresh probe must be zero-overlay no-US/no-update')
|
||||
sampler=processes['evaluation-inputs']['job']
|
||||
evidence.pin(Path(job['case_dir'])/'requests.npz',A.digest(Path(sampler['output_dir'])/'A-requests.npz'))
|
||||
context=dict(policy=POLICY,environment=brain['worker']['environment'],brain_sources=job['sources'],
|
||||
model={k:spec[k] for k in ('model','apl','dt_ms','precision','apl_precision','apl_delay_steps','graph_dir','apl_bundle_dir')},
|
||||
registered_sources_sha256=reg['source_sha256'],
|
||||
output_policy='retain_all_cycle_artifacts_plus_entire_final_cache_each_cycle; no amortization')
|
||||
contexts.append(context)
|
||||
observed=_cycle_files(name,rows,evidence)
|
||||
require(_same(cycle['output_inventory'],observed) and cycle['output_bytes']==sum(v['bytes'] for v in observed.values()),
|
||||
'Cycle created inventory is not actual complete fixed-branch scope')
|
||||
own=F.EXP/'receipts'/f'{name}.cycle.json';own_bytes=own.stat().st_size
|
||||
inventory=dict(created=observed,cycle_receipt=evidence.pin(own),cycle_receipt_bytes=own_bytes,
|
||||
full_current_build_cache=final_build,full_current_build_cache_bytes=build_bytes,
|
||||
total_bytes=cycle['output_bytes']+own_bytes+build_bytes)
|
||||
events=[]
|
||||
for (role,event_name),row in zip(roles,rows):
|
||||
p=row['process'];runtime=row['worker'].get('wall_seconds')
|
||||
require(_number(runtime) and runtime<=p['child_wall_seconds'],'Worker runtime duration missing/inconsistent')
|
||||
require(start<=p['spawn_monotonic'] and p['validation_end_monotonic']<=end,'Process outside actual cycle clock')
|
||||
events.append(dict(event_id=event_name,role=role,receipt_kind='parent-process',receipt=row['binding'],
|
||||
spawn_s=p['spawn_monotonic'],exit_s=p['exit_monotonic'],validated_s=p['validation_end_monotonic'],
|
||||
exit_code=0,core_seconds=None,runtime_seconds=runtime,child_wall_seconds=p['child_wall_seconds']))
|
||||
samples.append(dict(schema=B.SCHEMA,cycle_id=name,kind='training' if name==TRAIN else 'probe',
|
||||
diagnostic_mode='light',steps=1200,neurons=B.N,edges=B.E,dt_ms=.1,context_sha256=_sha(context),
|
||||
clock_id='registered-parent:'+reg_sha,started_s=start,validated_s=tail_end,
|
||||
authority=evidence.pin(own),events=events,outputs=dict(inventory=evidence.derived_binding(name,inventory),
|
||||
scope=B.OUTPUT_SCOPE,complete=True,total_bytes=inventory['total_bytes']),complete=True))
|
||||
accounts[name]=dict(recorded_cycle_seconds=end-start,tail_upper_bound_seconds=tail_end-end,
|
||||
conservative_complete_cycle_seconds=tail_end-start,tail_bound_from_next_cycle=next_name,
|
||||
tail_may_include_intervening_sampler=True,created_bytes=cycle['output_bytes'],cycle_receipt_bytes=own_bytes,
|
||||
repeated_full_cache_bytes=build_bytes,total_conservative_bytes=inventory['total_bytes'],
|
||||
core_timing=None,core_timing_reason='no unrounded authenticated core timing contract; never substituted for wall')
|
||||
require(_same(contexts[0],contexts[1]),'Train/probe machine/code/model/output policies differ')
|
||||
return samples,accounts,contexts[0]
|
||||
|
||||
|
||||
def report(reg_sha,save_report=True):
|
||||
"""Verify current bytes; optionally exclusively save audit/budget-report.json.
|
||||
|
||||
Missing evidence returns INSUFFICIENT; contradictory/tampered evidence raises.
|
||||
No full-suite numerical estimate is admitted without a future registered
|
||||
normal executor, growing-inventory hash policy and explicit complete reserves.
|
||||
"""
|
||||
require(type(save_report) is bool,'save_report must be Boolean')
|
||||
destination=F.EXP/'audit/budget-report.json'
|
||||
require(not save_report or not destination.exists(),'Budget report exists; never overwrite')
|
||||
reg=F.registration(reg_sha);evidence=Evidence();evidence.pin(F.EXP/'protocol/preregistered.json',reg_sha)
|
||||
samples=[];accounting={};context=None;missing=[]
|
||||
try:samples,accounting,context=_collect(reg,reg_sha,evidence)
|
||||
except FileNotFoundError as error:missing.append('Actual measurement evidence missing: '+str(error.filename))
|
||||
measured=[];used=set()
|
||||
for row in samples:measured.append(B._measure(row,evidence.authenticated(),used))
|
||||
# These explicit placeholders are supplied ONLY with zero admitted samples.
|
||||
# They are not assumptions of zero future cost and can never yield a total.
|
||||
blocked_reserves={role:dict(wall_seconds=0,output_bytes=0,basis='UNREGISTERED; not used for a projection') for role in B.RESERVE_ROLES}
|
||||
blocked_reserves['cycle_multiplier']=1
|
||||
projection=B.estimate_normal_suite([],authenticated_receipts={},target_context_sha256=reg_sha,
|
||||
reserves=blocked_reserves,limits=None)
|
||||
missing+=['FUTURE-POLICY-NOT-REGISTERED: normal executor/context and growing-output hashing/finalization policy',
|
||||
'FUTURE-POLICY-NOT-REGISTERED: explicit sampler/input, parent hash, final integrity, compiler/warmup and unknown-activity reserves',
|
||||
'FUTURE-POLICY-NOT-REGISTERED: normal wall/storage caps; engineering 4 GiB/7200 s is not a normal budget']
|
||||
value=dict(schema=SCHEMA,registration_sha256=reg_sha,status='INSUFFICIENT-MEASUREMENTS',
|
||||
policy_status='FUTURE-POLICY-NOT-REGISTERED',inventory=deepcopy(B.INVENTORY),measurements=measured,
|
||||
available_cost_cycles=samples,accounting=accounting,measured_context=context,
|
||||
measured_context_sha256=None if context is None else _sha(context),strict_projection=projection,
|
||||
estimated_wall_seconds=None,estimated_output_bytes=None,missing=missing,
|
||||
evidence_sha256=evidence.pins,derived_inventories=evidence.derived,
|
||||
verification_scope='registered parent receipts plus actual current bytes; historical OS exits are not re-observed',
|
||||
limitations=['only two fixed fresh light samples; no fitting, reference-to-light substitution or continuation extrapolation',
|
||||
'adjacent-cycle tail is a measured upper bound and may conservatively count intervening sampler work',
|
||||
'full final mutable cache is charged repeatedly for storage; compile/warmup wall for future policy remains unknown',
|
||||
'no assumption that activity/output volume remains constant after learning; no guaranteed full-suite bound',
|
||||
'shared registration/input preparation, final integrity and report own-file costs are not cycle costs'],
|
||||
engineering_scope=True,learning_pass_claimed=False,execution_authorized=False,
|
||||
assumptions_registered=False,normal_budget_authorized=False,no_new_brain_calls=True)
|
||||
F.verify(evidence.pins)
|
||||
if save_report:F.save(destination,value)
|
||||
return value
|
||||
@@ -0,0 +1,139 @@
|
||||
"""Build explicit file-bound authorities; does not run a brain or prove a process.
|
||||
|
||||
The registered coordinator authenticates source/input bytes and actual exits.
|
||||
All output here is a new dictionary; existing authority files are never edited.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import copy
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
||||
def require(ok, message):
|
||||
if not ok: raise ValueError(message)
|
||||
|
||||
|
||||
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 read(path):
|
||||
def unique(items):
|
||||
value={}
|
||||
for k,v in items:
|
||||
require(k not in value,'Duplicate JSON key');value[k]=v
|
||||
return value
|
||||
return json.loads(Path(path).read_text(encoding='utf-8'),object_pairs_hook=unique,
|
||||
parse_constant=lambda x: (_ for _ in ()).throw(ValueError('Nonfinite JSON')))
|
||||
|
||||
|
||||
def pin(path):
|
||||
p=Path(path)
|
||||
require(p.is_absolute() and p.is_file() and not any(x.is_symlink() for x in (p,*p.parents)),
|
||||
'Absolute unlinked regular source required')
|
||||
return dict(path=str(p.resolve()),sha256=digest(p))
|
||||
|
||||
|
||||
def files_from_authority(value):
|
||||
"""Exact direct closure. Parent full payload is additionally checked by loader."""
|
||||
result={}
|
||||
def add(path,sha):
|
||||
require(path not in result or result[path]==sha,'Conflicting input pin')
|
||||
result[path]=sha
|
||||
def visit(item):
|
||||
if type(item)is dict:
|
||||
if set(item)=={'path','sha256'}:add(item['path'],item['sha256'])
|
||||
else:
|
||||
for key,value in item.items():
|
||||
if key=='frozen_inputs':
|
||||
for path,sha in value.items():add(path,sha)
|
||||
else:visit(value)
|
||||
elif type(item)is list:
|
||||
for value in item:visit(value)
|
||||
visit(value)
|
||||
if 'parent' in value:
|
||||
p=value['parent'];add(str(Path(p['directory'])/'checkpoint-manifest.json'),p['checkpoint_manifest_sha256'])
|
||||
if 'checkpoint_dir' in value:
|
||||
add(str(Path(value['checkpoint_dir'])/'checkpoint-manifest.json'),value['checkpoint_manifest_sha256'])
|
||||
return result
|
||||
|
||||
|
||||
def effective_hash(spec,overlay_file):
|
||||
"""Independent original-base bridge, exact SI arithmetic and APL fast mask."""
|
||||
graph=Path(spec['graph_dir'])
|
||||
weights=np.load(graph/'weights.npy',allow_pickle=False)
|
||||
src=np.load(graph/'src.npy',allow_pickle=False,mmap_mode='r')
|
||||
ids=np.load(graph/'edge_id.npy',allow_pickle=False,mmap_mode='r')
|
||||
try:
|
||||
require(weights.dtype==np.float64 and weights.shape==(25582938,) and
|
||||
src.dtype==np.int32 and src.shape==weights.shape and ids.dtype==np.int64 and ids.shape==weights.shape,
|
||||
'Full canonical graph required')
|
||||
apl=np.load(Path(spec['apl_bundle_dir'])/'apl_globals.npy',allow_pickle=False)
|
||||
require(apl.dtype==np.int32 and apl.shape==(2,),'Two canonical APL IDs required')
|
||||
fast=np.isin(src,apl);require(int(fast.sum())==5845,'Original fast-APL mask differs')
|
||||
weights[fast]=np.float64(0)
|
||||
with np.load(overlay_file,allow_pickle=False) as f:
|
||||
require(set(f.files)=={'edge_id','plastic_delta_mv'},'Overlay array fields differ')
|
||||
mask=f['edge_id'];delta=f['plastic_delta_mv']
|
||||
require(mask.dtype==np.int64 and mask.shape==(14232,) and delta.dtype==np.float32 and delta.shape==mask.shape and
|
||||
np.all((mask>=0)&(mask<len(weights))) and np.all(mask[1:]>mask[:-1]) and
|
||||
np.array_equal(ids[mask],mask) and not fast[mask].any() and np.isfinite(delta).all() and np.all(delta<=0),
|
||||
'Original candidate overlay contract differs')
|
||||
nz=delta!=np.float32(0)
|
||||
rows=mask[nz]
|
||||
weights[rows]=np.add(weights[rows],np.multiply(delta[nz].astype(np.float64),np.float64(.001)))
|
||||
require(np.isfinite(weights).all() and np.all(weights[mask]>0),'Effective candidate sign/nonfinite failure')
|
||||
return hashlib.sha256(weights.astype('<f8',copy=False).tobytes()).hexdigest()
|
||||
finally:
|
||||
src._mmap.close();ids._mmap.close()
|
||||
|
||||
|
||||
def epoch_authority(template,*,case,checkpoint,overlay,epoch_id,us_tick,d_command=1.,frozen=False):
|
||||
value=copy.deepcopy(template)
|
||||
require(value['schema']=='phase4an-epoch-postprocess-authority-v1','Wrong epoch template')
|
||||
case,checkpoint=Path(case),Path(checkpoint)
|
||||
spec=read(case/'spec.json');summary=read(checkpoint/'summary.json')
|
||||
require(type(us_tick)is int and 0<=us_tick<spec['steps'] and summary['steps']==spec['steps'],'Invalid epoch clock')
|
||||
value.update(epoch_id=epoch_id,diagnostic_mode=summary['diagnostic_mode'],checkpoint_dir=str(checkpoint),
|
||||
checkpoint_manifest_sha256=digest(checkpoint/'checkpoint-manifest.json'))
|
||||
value['command']=dict(steps=spec['steps'],compartment="y5B'2a",us_tick=us_tick,
|
||||
d_command=d_command,frozen=frozen,trace_backend='torch')
|
||||
for role,path in dict(spec=case/'spec.json',requests=case/'requests.npz',state=checkpoint/'state.npz',
|
||||
overlay_before=overlay['overlay_file'],overlay_manifest_before=overlay['overlay_manifest']).items():
|
||||
value['files'][role]=pin(path)
|
||||
return value
|
||||
|
||||
|
||||
def boundary_authority(*,boundary_id,registration_sha256,case,parent,transition,input_policy,mode,
|
||||
before_overlay,after_overlay,source_files,frozen_inputs,epoch=None,update_dir=None,cpu_receipt=None):
|
||||
require(transition in ('epoch_update','idle') and mode in ('reference','light'),'Invalid transition/mode')
|
||||
case,parent=Path(case),Path(parent);spec=read(case/'spec.json');summary=read(parent/'summary.json')
|
||||
offset=summary.get('global_next_tick',summary['steps'])
|
||||
require(spec['global_tick_offset']==offset and spec['parent_checkpoint_manifest_sha256']==digest(parent/'checkpoint-manifest.json'),
|
||||
'Case does not identify exact parent/clock')
|
||||
before=effective_hash(spec,before_overlay['overlay_file']);after=effective_hash(spec,after_overlay['overlay_file'])
|
||||
require(before==summary['effective_weights_raw_sha256'],'Before effective weight is not parent installation')
|
||||
update=None
|
||||
if transition=='epoch_update':
|
||||
require(epoch is not None and update_dir is not None and cpu_receipt is not None,'Missing actual update evidence')
|
||||
update=dict(epoch_authority=pin(epoch),files={n:pin(Path(update_dir)/n) for n in
|
||||
('chain-receipt.json','update-receipt.json','delta-after.npz','overlay-manifest.json')})
|
||||
else:
|
||||
require(epoch is update_dir is cpu_receipt is None and before==after,'Idle cannot include a new update')
|
||||
return dict(schema='conditioning-updated-boundary-v1',boundary_id=boundary_id,registration_sha256=registration_sha256,
|
||||
transition=transition,diagnostic_mode=mode,input_policy=input_policy,
|
||||
case=dict(spec=pin(case/'spec.json'),requests=pin(case/'requests.npz')),
|
||||
parent=dict(directory=str(parent),checkpoint_manifest_sha256=digest(parent/'checkpoint-manifest.json')),
|
||||
global_tick_offset=offset,
|
||||
overlay_before=dict(file=pin(before_overlay['overlay_file']),manifest=pin(before_overlay['overlay_manifest'])),
|
||||
overlay_after=dict(file=pin(after_overlay['overlay_file']),manifest=pin(after_overlay['overlay_manifest'])),
|
||||
expected_effective_weight_before_sha256=before,expected_effective_weight_after_sha256=after,
|
||||
update=update,cpu_validation=None if cpu_receipt is None else pin(cpu_receipt),
|
||||
source_files=copy.deepcopy(source_files),frozen_inputs=copy.deepcopy(frozen_inputs))
|
||||
@@ -0,0 +1,168 @@
|
||||
"""Pure normal-suite cost proposal from externally authenticated parent receipts.
|
||||
|
||||
No process/file authentication occurs here. Every cycle, process event and full
|
||||
output inventory must be bound to a caller-authenticated receipt SHA. Parent
|
||||
monotonic stamps cover before-spawn through exit and independent postvalidation;
|
||||
worker slot/core timing is never an end-to-end measurement. All clocks within a
|
||||
cycle share its clock_id. Context SHA externally binds machine/code/runtime and
|
||||
the exact proposed execution/output-retention policy, not merely a GPU model.
|
||||
Observed maxima plus explicit reserves are conservative estimates, not guarantees
|
||||
for future learning-dependent activity. No fitting, shortening or authorization.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from copy import deepcopy
|
||||
import math
|
||||
|
||||
|
||||
SCHEMA = 'conditioning-cost-cycle-v1'
|
||||
N, E = 166700, 25582938
|
||||
INVENTORY = dict(training_calls=30000, probe_calls=3920, brain_calls=33920,
|
||||
steps_per_call=1200, total_steps=40704000, biological_seconds=4070.4,
|
||||
original_E_calls=30000, CPU_validator_calls=30000)
|
||||
RESERVE_ROLES = {'sampler_input', 'parent_hash', 'final_integrity', 'compiler_warmup', 'unknown_activity'}
|
||||
OUTPUT_SCOPE = 'entire_cycle_tree_including_inputs_build_logs_receipts'
|
||||
CYCLE_FIELDS = {'schema','cycle_id','kind','diagnostic_mode','steps','neurons','edges','dt_ms',
|
||||
'context_sha256','clock_id','started_s','validated_s','authority','events','outputs','complete'}
|
||||
EVENT_FIELDS = {'event_id','role','receipt_kind','receipt','spawn_s','exit_s','validated_s',
|
||||
'exit_code','core_seconds','runtime_seconds','child_wall_seconds'}
|
||||
|
||||
|
||||
def _require(ok, message):
|
||||
if not ok:
|
||||
raise ValueError(message)
|
||||
|
||||
|
||||
def _sha(value):
|
||||
return type(value) is str and len(value) == 64 and all(c in '0123456789abcdef' for c in value)
|
||||
|
||||
|
||||
def _number(value):
|
||||
return type(value) in (int,float) and math.isfinite(value) and value >= 0
|
||||
|
||||
|
||||
def _text(value):
|
||||
return type(value) is str and bool(value) and value.strip() == value
|
||||
|
||||
|
||||
def _binding(value, authenticated):
|
||||
_require(type(value) is dict and set(value) == {'receipt_id','sha256'} and
|
||||
_text(value['receipt_id']) and _sha(value['sha256']) and
|
||||
authenticated.get(value['receipt_id']) == value['sha256'], 'Unauthenticated receipt descriptor')
|
||||
|
||||
|
||||
def _measure(row, authenticated, used):
|
||||
_require(type(row) is dict and set(row) == CYCLE_FIELDS and row['schema'] == SCHEMA and
|
||||
row['complete'] is True, 'Explicit complete authoritative cycle required; no worker-slot adapter')
|
||||
_require(_text(row['cycle_id']) and _text(row['clock_id']) and _sha(row['context_sha256']), 'Missing cycle identity/context/clock')
|
||||
_binding(row['authority'], authenticated)
|
||||
_require(row['kind'] in ('training','probe','state_only_idle') and
|
||||
row['diagnostic_mode'] in ('light','reference'), 'Unsupported cycle kind/mode')
|
||||
_require(type(row['steps']) is int and row['steps'] > 0 and type(row['neurons']) is int and
|
||||
row['neurons'] == N and type(row['edges']) is int and row['edges'] == E and
|
||||
type(row['dt_ms']) in (int,float) and row['dt_ms'] == .1, 'Full frozen graph/clock required')
|
||||
_require(all(_number(row[k]) for k in ('started_s','validated_s')) and
|
||||
row['validated_s'] > row['started_s'], 'Invalid whole-cycle timing')
|
||||
events = row['events']
|
||||
roles = ['brain','original_E','cpu_validator'] if row['kind'] == 'training' else ['brain']
|
||||
_require(type(events) is list and [e.get('role') for e in events if type(e) is dict] == roles,
|
||||
'Training requires brain + original E + CPU validator; probes/idle must not update')
|
||||
previous, totals = row['started_s'], dict(core_seconds=0.,runtime_seconds=0.,child_wall_seconds=0.)
|
||||
measured = {key: True for key in totals}
|
||||
receipt_ids = [row['authority']['receipt_id']]
|
||||
for event in events:
|
||||
_require(type(event) is dict and set(event) == EVENT_FIELDS and _text(event['event_id']) and
|
||||
('event',event['event_id']) not in used and event['receipt_kind'] == 'parent-process' and
|
||||
type(event['exit_code']) is int and event['exit_code'] == 0, 'Actual successful unique parent process required')
|
||||
used.add(('event',event['event_id']))
|
||||
_binding(event['receipt'], authenticated)
|
||||
receipt_ids.append(event['receipt']['receipt_id'])
|
||||
_require(all(_number(event[k]) for k in ('spawn_s','exit_s','validated_s')) and
|
||||
previous <= event['spawn_s'] < event['exit_s'] <= event['validated_s'] <= row['validated_s'],
|
||||
'Event clock ordering/whole-cycle binding failed')
|
||||
previous = event['validated_s']
|
||||
child = event['exit_s'] - event['spawn_s']
|
||||
_require(_number(event['child_wall_seconds']) and math.isclose(event['child_wall_seconds'],child,rel_tol=1e-12),
|
||||
'Child wall must be actual parent spawn-to-exit time')
|
||||
upper = child
|
||||
for key in ('runtime_seconds','core_seconds'):
|
||||
value = event[key]
|
||||
if value is not None:
|
||||
_require(_number(value) and value <= upper, 'Core/runtime/child timing layers inconsistent')
|
||||
upper = value
|
||||
for key in totals:
|
||||
if event[key] is None:
|
||||
measured[key] = False
|
||||
else:
|
||||
totals[key] += event[key]
|
||||
outputs = row['outputs']
|
||||
_require(type(outputs) is dict and set(outputs) == {'inventory','scope','complete','total_bytes'} and
|
||||
outputs['scope'] == OUTPUT_SCOPE and outputs['complete'] is True and
|
||||
type(outputs['total_bytes']) is int and outputs['total_bytes'] > 0, 'Actual complete cycle output inventory required')
|
||||
_binding(outputs['inventory'], authenticated)
|
||||
receipt_ids.append(outputs['inventory']['receipt_id'])
|
||||
_require(len(set(receipt_ids)) == len(receipt_ids), 'Cycle/event/output receipts must have distinct identities')
|
||||
_require(not any(('receipt',key) in used for key in receipt_ids), 'Receipt reused across purported independent cycles')
|
||||
used.update(('receipt',key) for key in receipt_ids)
|
||||
return dict(cycle_id=row['cycle_id'], kind=row['kind'], diagnostic_mode=row['diagnostic_mode'],
|
||||
steps=row['steps'], context_sha256=row['context_sha256'],
|
||||
timing={**{k: totals[k] if measured[k] else None for k in totals},
|
||||
'end_to_end_seconds':row['validated_s']-row['started_s']}, output_bytes=outputs['total_bytes'])
|
||||
|
||||
|
||||
def estimate_normal_suite(cycles, *, authenticated_receipts, target_context_sha256, reserves, limits=None):
|
||||
"""Return proposal or INSUFFICIENT-MEASUREMENTS, never permission to execute.
|
||||
|
||||
reserves requires cycle_multiplier>=1 plus all RESERVE_ROLES, each with
|
||||
wall_seconds/output_bytes/basis. Explicit zero is permitted with a stated
|
||||
basis (e.g. already included); none are silently assumed zero. limits, when
|
||||
supplied, must specify wall_seconds and output_bytes caps for this proposal.
|
||||
Only matched-context light complete 1200-tick cycles enter extrapolation.
|
||||
"""
|
||||
_require(type(cycles) is list and type(authenticated_receipts) is dict and
|
||||
all(_text(k) and _sha(v) for k,v in authenticated_receipts.items()) and
|
||||
_sha(target_context_sha256), 'Explicit authenticated receipt/context descriptors required')
|
||||
_require(type(reserves) is dict and set(reserves) == RESERVE_ROLES | {'cycle_multiplier'} and
|
||||
_number(reserves['cycle_multiplier']) and reserves['cycle_multiplier'] >= 1, 'Explicit complete reserves required')
|
||||
for role in RESERVE_ROLES:
|
||||
reserve = reserves[role]
|
||||
_require(type(reserve) is dict and set(reserve) == {'wall_seconds','output_bytes','basis'} and
|
||||
_number(reserve['wall_seconds']) and type(reserve['output_bytes']) is int and
|
||||
reserve['output_bytes'] >= 0 and _text(reserve['basis']), 'Invalid explicit reserve: '+role)
|
||||
if limits is not None:
|
||||
_require(type(limits) is dict and set(limits) == {'wall_seconds','output_bytes'} and
|
||||
_number(limits['wall_seconds']) and limits['wall_seconds'] > 0 and
|
||||
type(limits['output_bytes']) is int and limits['output_bytes'] > 0, 'Invalid resource caps')
|
||||
used = set()
|
||||
measured = [_measure(row,authenticated_receipts,used) for row in cycles]
|
||||
_require(len({r['cycle_id'] for r in measured}) == len(measured), 'Duplicate cycles')
|
||||
eligible = {kind:[r for r in measured if r['kind'] == kind and r['diagnostic_mode'] == 'light' and
|
||||
r['steps'] == 1200 and r['context_sha256'] == target_context_sha256] for kind in ('training','probe')}
|
||||
missing = [kind+' complete matched-context light 1200-tick cycle' for kind,rows in eligible.items() if not rows]
|
||||
result = dict(status='INSUFFICIENT-MEASUREMENTS' if missing else 'ESTIMATED-NOT-AUTHORIZED',
|
||||
inventory=deepcopy(INVENTORY), measured_cycles=measured, missing=missing,
|
||||
eligible_cycle_ids={kind:[r['cycle_id'] for r in rows] for kind,rows in eligible.items()},
|
||||
symbolic_wall='cycle_multiplier * (30000 * max(train_end_to_end) + 3920 * max(probe_end_to_end)) + explicit_reserves',
|
||||
symbolic_storage='cycle_multiplier * (30000 * max(train_full_bytes) + 3920 * max(probe_full_bytes)) + explicit_reserves',
|
||||
estimated_wall_seconds=None, estimated_output_bytes=None, caps=deepcopy(limits), caps_pass=None,
|
||||
reserves=deepcopy(reserves), basis='observed maxima; no fitted throughput, amortization or deletion assumptions',
|
||||
limitations=['caller authenticates receipt bytes, event identity, complete inventories and execution context',
|
||||
'reference and state-only idle are diagnostics only, never light training performance',
|
||||
'observed maxima cannot bound unobserved learning-dependent activity or contention',
|
||||
'retains every measured cycle output; no assumed cleanup/deduplication/compression gain',
|
||||
'reserve coverage and sufficiency remain caller responsibilities; no guarantee'],
|
||||
engineering_scope='measurement/interface evidence only, not learning PASS',
|
||||
external_identity_verified_here=False, scientific_learning_claimed=False, execution_authorized=False,
|
||||
on_limit='STOP; never_reduce_inventory_or_shorten_trials')
|
||||
if missing:
|
||||
return result
|
||||
count = {'training':30000,'probe':3920}
|
||||
wall = sum(count[k]*max(r['timing']['end_to_end_seconds'] for r in rows) for k,rows in eligible.items())
|
||||
size = sum(count[k]*max(r['output_bytes'] for r in rows) for k,rows in eligible.items())
|
||||
result['estimated_wall_seconds'] = math.ceil(reserves['cycle_multiplier']*wall + sum(reserves[k]['wall_seconds'] for k in RESERVE_ROLES))
|
||||
result['estimated_output_bytes'] = math.ceil(reserves['cycle_multiplier']*size + sum(reserves[k]['output_bytes'] for k in RESERVE_ROLES))
|
||||
if limits is not None:
|
||||
result['caps_pass'] = result['estimated_wall_seconds'] <= limits['wall_seconds'] and result['estimated_output_bytes'] <= limits['output_bytes']
|
||||
if not result['caps_pass']:
|
||||
result['status'] = 'STOP-BUDGET-EXCEEDED'
|
||||
return result
|
||||
@@ -0,0 +1,320 @@
|
||||
"""Finite, process-isolated boundary experiment; NOT the conditioning runner.
|
||||
|
||||
Requires external preregistration SHA and exclusive outputs. No automatic retry.
|
||||
The old AP worker is invoked as an executable only, never imported as a neural
|
||||
module into this coordinator. Every child exit and output inventory is checked.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import copy
|
||||
from datetime import datetime, timezone
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
import traceback
|
||||
|
||||
import numpy as np
|
||||
|
||||
import boundary_plan as PLAN
|
||||
import execution_authority as A
|
||||
import isolated_execution as W
|
||||
from prepare_execution import ROOT, MODEL, EXP, AP, LAB, save, save_npz, npz, verify, copy_exclusive
|
||||
|
||||
require,read,digest=A.require,A.read,A.digest
|
||||
AP_WORKER=MODEL.parent/'conditioning-interface-v2/isolated_workers.py'
|
||||
|
||||
|
||||
def registration(expected):
|
||||
file=EXP/'protocol/preregistered.json'
|
||||
require(digest(file)==expected,'External registration SHA changed')
|
||||
reg=read(file)
|
||||
require(reg['schema']=='conditioning-execution-registration-v1' and reg['engineering_only'] is True and
|
||||
reg['scientific_acquisition_authorized'] is False,'Wrong experiment authority')
|
||||
PLAN.validate_plan(reg['plan'])
|
||||
verify({**reg['source_sha256'],**reg['input_sha256'],**reg['prepared_file_sha256']})
|
||||
return reg
|
||||
|
||||
|
||||
def tree(directory,*,exclude_build=False):
|
||||
result={}
|
||||
for p in sorted(Path(directory).rglob('*')):
|
||||
require(not p.is_symlink(),'Linked output forbidden')
|
||||
if exclude_build and p.relative_to(directory).parts[0]=='extension-build':continue
|
||||
if p.is_file():result[p.relative_to(directory).as_posix()]=dict(sha256=digest(p),bytes=p.stat().st_size)
|
||||
else:require(p.is_dir(),'Nonregular output forbidden')
|
||||
return result
|
||||
|
||||
|
||||
class Workflow:
|
||||
def __init__(self,sha):
|
||||
self.started=time.perf_counter();self.sha=sha;self.reg=registration(sha)
|
||||
self.deadline=self.started+self.reg['budget']['workflow_timeout_seconds']
|
||||
self.parents=copy.deepcopy(self.reg['parent_records']);self.jobs={};self.boundaries={}
|
||||
self.completed=[];self.cycles=[];self.sampler=None
|
||||
self.h=W.ap_helpers()
|
||||
|
||||
def admission(self):
|
||||
require(time.perf_counter()<self.deadline,'Whole-workflow wall limit reached')
|
||||
require(not any((EXP/n).exists() for n in ('audit/stopped.json','audit/execution-complete.json','manifest.json')),
|
||||
'Stopped/completed workflow cannot be retried')
|
||||
budget=self.reg['budget'];used=sum(p.stat().st_size for p in EXP.rglob('*') if p.is_file())
|
||||
require(used<=budget['output_cap_bytes'] and shutil.disk_usage(EXP).free>=
|
||||
budget['minimum_free_reserve_bytes']+max(0,budget['output_cap_bytes']-used),'Finite disk cap/reserve exceeded')
|
||||
|
||||
def allpins(self):
|
||||
return {**self.reg['source_sha256'],**self.reg['input_sha256'],**self.reg['prepared_file_sha256'],
|
||||
str(EXP/'protocol/preregistered.json'):self.sha}
|
||||
|
||||
def launch(self,name,job,*,ap=False):
|
||||
self.admission()
|
||||
loc={n:EXP/f'{sub}/{name}{suffix}' for n,sub,suffix in
|
||||
(('job','jobs','.json'),('receipt','receipts','.worker.json'),('process','receipts','.process.json'),
|
||||
('stdout','logs','.stdout.log'),('stderr','logs','.stderr.log'))}
|
||||
require(not any(p.exists() for p in loc.values()),'Exclusive process record exists; no retry')
|
||||
require(job['receipt_file']==str(loc['receipt']),'Receipt location differs')
|
||||
save(loc['job'],job);jobsha=digest(loc['job'])
|
||||
script=AP_WORKER if ap else MODEL/'isolated_execution.py'
|
||||
command=[sys.executable,'-B',str(script)]
|
||||
if ap:command.append(job['kind'])
|
||||
command+=['--job',str(loc['job']),'--job-sha256',jobsha]
|
||||
start=time.perf_counter();started_utc=datetime.now(timezone.utc).isoformat()
|
||||
timeout=min(self.reg['budget']['child_timeout_seconds'],self.deadline-start)
|
||||
require(timeout>0,'No remaining workflow wall allowance')
|
||||
timed_out=False;exit_code=None
|
||||
with loc['stdout'].open('xb') as out,loc['stderr'].open('xb') as err:
|
||||
try:exit_code=subprocess.run(command,cwd=MODEL,stdout=out,stderr=err,timeout=timeout).returncode
|
||||
except subprocess.TimeoutExpired:timed_out=True
|
||||
exited=time.perf_counter()
|
||||
base=dict(schema='conditioning-execution-process-v1',name=name,kind=job['kind'],registration_sha256=self.sha,
|
||||
argv=command,job_sha256=jobsha,exit_code=exit_code,timed_out=timed_out,started_utc=started_utc,
|
||||
spawn_monotonic=start,exit_monotonic=exited,child_wall_seconds=exited-start,
|
||||
stdout_sha256=digest(loc['stdout']),stderr_sha256=digest(loc['stderr']))
|
||||
try:
|
||||
require(exit_code==0 and not timed_out and loc['receipt'].is_file(),'Child failed; preserve partial outputs')
|
||||
receipt=read(loc['receipt']);expected='phase4ap-isolated-worker-receipt-v1' if ap else 'conditioning-isolated-execution-receipt-v1'
|
||||
require(receipt['schema']==expected and receipt['complete'] is True and receipt['job_sha256']==jobsha and
|
||||
receipt['registration_sha256']==self.sha and receipt['kind']==job['kind'] and
|
||||
receipt['job_id']==job['job_id'] and receipt['worker_sha256']==job['worker_sha256'],
|
||||
'Real worker receipt identity differs')
|
||||
expectedpins={**job['input_sha256'],str(loc['job']):jobsha,str(script):job['worker_sha256']}
|
||||
if not ap:
|
||||
expectedpins[str(AP_WORKER)]=W.AP_SHA
|
||||
expectedpins.update({str(MODEL/n):s for n,s in job['source_sha256'].items()})
|
||||
else:expectedpins.update({v['path']:v['sha256'] for v in job['sources'].values()})
|
||||
require(receipt['verified_input_sha256' if ap else 'input_sha256']==expectedpins,
|
||||
'Child did not verify exact external source/input closure')
|
||||
actual={k:v['sha256'] for k,v in tree(Path(job['output_dir'])).items()}
|
||||
require(actual and actual==receipt['output_files_sha256'] and receipt['output_dir']==job['output_dir'],
|
||||
'Actual output inventory differs from successful worker')
|
||||
require(digest(str(loc['receipt'])+'.attempt.json')==receipt['attempt_sha256'],'Attempt record changed')
|
||||
verify(expectedpins);self.admission()
|
||||
end=time.perf_counter()
|
||||
record=dict(base,complete=True,worker_receipt_sha256=digest(loc['receipt']),
|
||||
validation_end_monotonic=end,end_to_end_seconds=end-start,validation_wall_seconds=end-exited,
|
||||
output_bytes=sum(v['bytes'] for v in tree(Path(job['output_dir'])).values()),
|
||||
output_inventory_sha256=hashlib.sha256(json.dumps(actual,sort_keys=True).encode()).hexdigest(),
|
||||
timing_scope='before child spawn through actual exit and independent parent file verification')
|
||||
save(loc['process'],record)
|
||||
except BaseException as exc:
|
||||
if not loc['process'].exists():save(loc['process'],dict(base,complete=False,error_type=type(exc).__name__,error=str(exc)))
|
||||
raise
|
||||
self.jobs[name]=dict(loc={k:str(v) for k,v in loc.items()},job=job,process=record,receipt=receipt)
|
||||
print(json.dumps(dict(child=name,complete=True,end_to_end_seconds=record['end_to_end_seconds']),sort_keys=True),flush=True)
|
||||
return receipt
|
||||
|
||||
def new_job(self,name,kind,authority,*,output=None,**extra):
|
||||
auth=read(authority);pins=self.allpins();pins[str(authority)]=digest(authority)
|
||||
if kind=='sample':pass
|
||||
else:pins.update(A.files_from_authority(auth))
|
||||
return dict(schema=W.SCHEMA,job_id=name,kind=kind,registration_sha256=self.sha,
|
||||
worker_sha256=self.reg['source_sha256'][str(MODEL/'isolated_execution.py')],
|
||||
source_sha256={n:self.reg['source_sha256'][str(MODEL/n)] for n in W.SOURCES[kind]},input_sha256=pins,
|
||||
output_dir=str(output or EXP/'runs'/name),receipt_file=str(EXP/'receipts'/f'{name}.worker.json'),
|
||||
budget={k:self.reg['budget'][k] for k in ('root','output_cap_bytes','minimum_free_reserve_bytes')},
|
||||
authority_file=str(authority),authority_sha256=digest(authority),**extra)
|
||||
|
||||
def ap_job(self,name,kind,*,case=None,overlay=None,authority=None,output):
|
||||
pins=self.allpins()
|
||||
job=dict(schema='phase4ap-isolated-worker-job-v1',job_id=name,kind=kind,registration_sha256=self.sha,
|
||||
worker_sha256=W.AP_SHA,output_dir=str(output),receipt_file=str(EXP/'receipts'/f'{name}.worker.json'))
|
||||
if kind=='brain':
|
||||
for path in (case/'spec.json',case/'requests.npz',overlay['overlay_file'],overlay['overlay_manifest']):pins[str(path)]=digest(path)
|
||||
job.update(case_dir=str(case),build_root=str(EXP/'extension-build'),**overlay,diagnostic_mode='light' if name.startswith('performance') else 'reference',
|
||||
admission=dict(gpu_uuid=self.h.GPU,comfy_queue_urls=list(self.h.COMFY_URLS)),
|
||||
sources={n:dict(path=str(LAB/(n+'.py')),sha256=self.h.SOURCE_PINS[n]) for n in ('runtime_light','runtime_continuation')})
|
||||
else:
|
||||
value=read(authority);pins.update(A.files_from_authority(value));pins[str(authority)]=digest(authority)
|
||||
job.update(authority_file=str(authority),authority_sha256=digest(authority),
|
||||
sources={'conditioning_epoch':dict(path=str(LAB/'conditioning_epoch.py'),sha256=self.h.SOURCE_PINS['conditioning_epoch'])})
|
||||
job['input_sha256']=pins
|
||||
return job
|
||||
|
||||
def cpu_verify(self,key,parent):
|
||||
name=key+'--cpu-verify';authority=Path(parent['epoch_authority']['path']);update=Path(parent['update_dir'])
|
||||
job=self.new_job(name,'validate_cpu',authority,update_dir=str(update),chain_sha256=digest(update/'chain-receipt.json'))
|
||||
# Original epoch authority doesn't include its future update files.
|
||||
job['input_sha256'].update({str(p):digest(p) for p in update.iterdir()})
|
||||
self.launch(name,job)
|
||||
parent['cpu_validation']=str(Path(job['output_dir'])/'validation.json')
|
||||
|
||||
def materialize(self,call,parent=None):
|
||||
group=call['case_group'];case=EXP/'cases'/group
|
||||
spec=read(self.reg['case_templates'][group])
|
||||
if parent is not None:
|
||||
spec.update(parent_checkpoint_manifest_sha256=parent['checkpoint_sha256'],global_tick_offset=call['global_tick_offset'])
|
||||
if call['runner']=='runtime_light' and call['call_id'].startswith('performance'):
|
||||
request=Path(self.parents[self.reg['plan']['imported_parents']['D1']['role']]['epoch_authority']['path'])
|
||||
source=Path(read(request)['files']['requests']['path']);arrays=None
|
||||
elif call['runner']=='runtime_light':source=EXP/'inputs/static/mechanical-requests.npz';arrays=None
|
||||
elif call['runner']=='boundary_oracle':
|
||||
pp=self.parents[call['prefix_replay_parent']]
|
||||
arrays=npz(read(pp['epoch_authority']['path'])['files']['requests']['path']);source=None
|
||||
elif call['input_policy']=='externally_pinned_CS_probe':
|
||||
require(self.sampler is not None,'Evaluation input not actually sampled')
|
||||
source=Path(self.sampler['output_dir'])/f"{call['cue']}-requests.npz";arrays=None
|
||||
else:source=None;arrays=dict(tick=np.empty(0,np.int32),neuron_idx=np.empty(0,np.int32))
|
||||
if case.exists():
|
||||
require(read(case/'spec.json')==spec,'Shared case metadata differs')
|
||||
if source:require(digest(case/'requests.npz')==digest(source),'Shared saved inputs differ')
|
||||
else:require(all(npz(case/'requests.npz')[k].tobytes()==v.tobytes() for k,v in arrays.items()),'Shared request arrays differ')
|
||||
else:
|
||||
case.mkdir();save(case/'spec.json',spec)
|
||||
if source:copy_exclusive(source,case/'requests.npz')
|
||||
else:save_npz(case/'requests.npz',arrays)
|
||||
return case
|
||||
|
||||
def sources(self,epoch):
|
||||
files=copy.deepcopy(epoch['files'])
|
||||
roles=('runtime_continuation_source','runtime_light_source','conditioning_update_source',
|
||||
'eligibility_bridge_source','phase4j_source','am_overlay_source')
|
||||
result={r:files[r] for r in roles}
|
||||
for role,name in (('conditioning_epoch_source','conditioning_epoch.py'),
|
||||
('conditioning_preflight_compare_source','conditioning_preflight_compare.py'),
|
||||
('engineering_compare_source','engineering_compare.py')):result[role]=A.pin(LAB/name)
|
||||
for role,name in (('updated_continuation_source','updated_continuation.py'),('cpu_validator_source','validate_update_cpu.py')):
|
||||
result[role]=A.pin(MODEL/name)
|
||||
return result
|
||||
|
||||
def boundary(self,call,case,parent):
|
||||
transition=call['transition'];epoch=read(parent['epoch_authority']['path'])
|
||||
before=parent['before_overlay'] if transition=='epoch_update' else parent['after_overlay']
|
||||
path=EXP/'authorities'/f"{call['call_id']}.json"
|
||||
value=A.boundary_authority(boundary_id=call['call_id'],registration_sha256=self.sha,case=case,parent=parent['directory'],
|
||||
transition=transition,input_policy=call['input_policy'],mode=call['diagnostic_mode'],
|
||||
before_overlay=before,after_overlay=parent['after_overlay'],source_files=self.sources(epoch),frozen_inputs=epoch['frozen_inputs'],
|
||||
epoch=parent['epoch_authority']['path'] if transition=='epoch_update' else None,
|
||||
update_dir=parent['update_dir'] if transition=='epoch_update' else None,
|
||||
cpu_receipt=parent['cpu_validation'] if transition=='epoch_update' else None)
|
||||
save(path,value);self.boundaries[call['call_id']]=path
|
||||
return path
|
||||
|
||||
def fresh(self,call):
|
||||
name=call['call_id'];case=self.materialize(call)
|
||||
performance=name.startswith('performance')
|
||||
prior=self.parents[self.reg['plan']['imported_parents']['D1']['role']]
|
||||
overlay=prior['before_overlay'] if performance else self.reg['initial_overlay']
|
||||
output=EXP/'runs'/name
|
||||
result=self.launch(name,self.ap_job(name,'brain',case=case,overlay=overlay,output=output),ap=True)
|
||||
auth=EXP/'authorities'/f'{name}.epoch.json'
|
||||
value=A.epoch_authority(read(prior['epoch_authority']['path']),case=case,checkpoint=output,overlay=overlay,
|
||||
epoch_id=name,us_tick=900 if performance else 1199)
|
||||
save(auth,value);update=EXP/'updates'/name
|
||||
self.launch(name+'--original-E',self.ap_job(name+'--original-E','update',authority=auth,output=update),ap=True)
|
||||
parent=dict(directory=str(output),checkpoint_sha256=result['result']['checkpoint_manifest_sha256'],
|
||||
epoch_authority=A.pin(auth),update_dir=str(update),before_overlay=overlay,
|
||||
after_overlay=dict(overlay_file=str(update/'delta-after.npz'),overlay_manifest=str(update/'overlay-manifest.json')))
|
||||
self.cpu_verify(name,parent);self.parents[name]=parent
|
||||
return result
|
||||
|
||||
def execute_call(self,call):
|
||||
name=call['call_id'];runner=call['runner']
|
||||
if runner=='runtime_light':return self.fresh(call)
|
||||
if runner=='fresh_probe':
|
||||
require(call.get('US') is False and call.get('plastic_update') is False and
|
||||
call.get('feedback_to_idle') is False and call['parent'] is None and
|
||||
call['overlay_after_role']=='AP.initial_overlay','Fresh probe scope differs')
|
||||
case=self.materialize(call)
|
||||
output=EXP/'runs'/name
|
||||
result=self.launch(name,self.ap_job(name,'brain',case=case,overlay=self.reg['initial_overlay'],output=output),ap=True)
|
||||
return result
|
||||
if runner=='boundary_oracle':
|
||||
ref='mechanical--updated--reference' if name.startswith('mechanical') else 'D1--updated--reference'
|
||||
authority=self.boundaries[ref];case=self.materialize(call)
|
||||
job=self.new_job(name,'oracle',authority,build_root=str(EXP/'extension-build'),oracle_case=str(case),
|
||||
oracle_spec_sha256=digest(case/'spec.json'),oracle_requests_sha256=digest(case/'requests.npz'))
|
||||
job['input_sha256'].update({str(case/n):digest(case/n) for n in ('spec.json','requests.npz')})
|
||||
else:
|
||||
parent=self.parents[call['parent']];case=self.materialize(call,parent)
|
||||
if runner=='runtime_continuation':
|
||||
authority=self.boundaries[name.split('--')[0]+'--updated--reference']
|
||||
job=self.new_job(name,'unchanged',authority,case_dir=str(case),build_root=str(EXP/'extension-build'),
|
||||
diagnostic_mode='reference',checkpoint_dir=parent['directory'],checkpoint_sha256=parent['checkpoint_sha256'],**parent['before_overlay'])
|
||||
else:
|
||||
if call['input_policy']=='externally_pinned_CS_probe':
|
||||
require(call.get('US') is False and call.get('plastic_update') is False and call.get('feedback_to_idle') is False,
|
||||
'Probe cannot request US, updates, or feed idle')
|
||||
authority=self.boundary(call,case,parent)
|
||||
job=self.new_job(name,'updated',authority,build_root=str(EXP/'extension-build'),diagnostic_mode=call['diagnostic_mode'])
|
||||
result=self.launch(name,job)
|
||||
if runner=='updated_continuation':
|
||||
parent=self.parents[call['parent']]
|
||||
self.parents[name]={**copy.deepcopy(parent), 'directory':job['output_dir'],
|
||||
'checkpoint_sha256':result['result']['checkpoint_manifest_sha256'],
|
||||
'before_overlay':parent['after_overlay']}
|
||||
return result
|
||||
|
||||
def run(self):
|
||||
attempt=EXP/'audit/execution-attempt.json'
|
||||
require(not attempt.exists(),'Workflow already attempted; no automatic retry')
|
||||
save(attempt,dict(registration_sha256=self.sha,started_utc=datetime.now(timezone.utc).isoformat(),
|
||||
pid=os.getpid(),monotonic_origin=self.started,no_automatic_retry=True))
|
||||
for arm,descriptor in self.reg['plan']['imported_parents'].items():self.cpu_verify('AP-'+arm,self.parents[descriptor['role']])
|
||||
for call in self.reg['plan']['calls']:
|
||||
if call['input_policy']=='externally_pinned_CS_probe' and self.sampler is None:
|
||||
job=self.new_job('evaluation-inputs','sample',EXP/'protocol/preregistered.json')
|
||||
self.sampler=self.launch('evaluation-inputs',job)
|
||||
started=time.perf_counter();before=tree(EXP,exclude_build=True)
|
||||
build_before=tree(EXP/'extension-build') if (EXP/'extension-build').is_dir() else {}
|
||||
self.execute_call(call)
|
||||
after=tree(EXP,exclude_build=True)
|
||||
build_after=tree(EXP/'extension-build') if (EXP/'extension-build').is_dir() else {}
|
||||
end=time.perf_counter()
|
||||
self.admission()
|
||||
require(all(k in after and after[k]==v for k,v in before.items()),'Earlier output was modified')
|
||||
created={k:v for k,v in after.items() if k not in before}
|
||||
record=dict(call=call,complete=True,start_monotonic=started,end_monotonic=end,wall_seconds=end-started,
|
||||
output_inventory=created,output_bytes=sum(v['bytes'] for v in created.values()),
|
||||
mutable_build_inventory_before=build_before,mutable_build_inventory_after=build_after,
|
||||
mutable_build_bytes_before=sum(v['bytes'] for v in build_before.values()),
|
||||
mutable_build_bytes_after=sum(v['bytes'] for v in build_after.values()),
|
||||
inventory_scope='all new immutable artifacts; separate actual mutable build before/after inventory; shared prior setup excluded',
|
||||
source_registration_sha256=self.sha,learning_pass_claimed=False)
|
||||
save(EXP/'receipts'/f"{call['call_id']}.cycle.json",record)
|
||||
self.cycles.append(record);self.completed.append(call['call_id'])
|
||||
self.admission()
|
||||
require(len(self.completed)==self.reg['plan']['counts']['new_brain_calls'] and
|
||||
len(self.jobs)==self.reg['plan']['counts']['total_children'],'Actual finite call inventory differs')
|
||||
self.admission()
|
||||
save(EXP/'audit/execution-complete.json',dict(complete=True,registration_sha256=self.sha,
|
||||
completed_calls=self.completed,processes={k:v['loc']['process'] for k,v in self.jobs.items()},
|
||||
boundary_authorities={k:str(v) for k,v in self.boundaries.items()},parents=self.parents,
|
||||
wall_seconds=time.perf_counter()-self.started,numerical_comparison_complete=False,
|
||||
scientific_learning_pass_claimed=False,candidate_generated=False))
|
||||
|
||||
|
||||
if __name__=='__main__':
|
||||
parser=argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--registration-sha256',required=True)
|
||||
args=parser.parse_args()
|
||||
try:Workflow(args.registration_sha256).run()
|
||||
except BaseException as exc:
|
||||
stop=EXP/'audit/stopped.json'
|
||||
if stop.parent.is_dir() and not stop.exists():save(stop,dict(complete=False,error_type=type(exc).__name__,error=str(exc),
|
||||
registration_sha256=args.registration_sha256,retry_forbidden=True,traceback=traceback.format_exc()))
|
||||
raise
|
||||
@@ -0,0 +1,124 @@
|
||||
"""Exclusive finite engineering seal; never creates a learned candidate.
|
||||
|
||||
Run only after independent numerical/budget reports and a NEW integrity process.
|
||||
Report hashes are external arguments. Historical regression evidence is preserved,
|
||||
not relabeled as a newly executed five-trial numerical regression.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import sys
|
||||
from types import ModuleType
|
||||
|
||||
import execution_authority as A
|
||||
from prepare_execution import ROOT, EXP, MODEL, save, verify
|
||||
|
||||
HELPER = ROOT/'models/male-cns-lif/pn-recruitment-audit-v1/publication.py'
|
||||
HELPER_SHA = '7a79c499098b74163e7bb16adabcbc54e7069dafa204d0b99c7f4c03d79f8016'
|
||||
require, read, digest = A.require, A.read, A.digest
|
||||
|
||||
|
||||
def helper():
|
||||
raw = HELPER.read_bytes()
|
||||
require(hashlib.sha256(raw).hexdigest() == HELPER_SHA, 'Frozen seal verifier changed')
|
||||
module = ModuleType('_execution_seal_pure_verifier')
|
||||
module.__file__ = str(HELPER)
|
||||
exec(compile(raw, str(HELPER), 'exec'), module.__dict__)
|
||||
return module
|
||||
|
||||
|
||||
def seal(directory):
|
||||
directory = Path(directory)
|
||||
require(directory.is_absolute() and directory.is_dir(), 'Exact real seal root required')
|
||||
require(not any((directory/n).exists() for n in ('manifest.json', 'checksums.sha256')), 'Never replace seal controls')
|
||||
paths = sorted(directory.rglob('*'))
|
||||
require(all(not p.is_symlink() and not (hasattr(p, 'is_junction') and p.is_junction()) and
|
||||
'__pycache__' not in p.parts and (p.is_file() or p.is_dir()) for p in (directory, *paths)),
|
||||
'Unsafe seal payload')
|
||||
files = [dict(path=p.relative_to(directory).as_posix(), bytes=p.stat().st_size, sha256=digest(p))
|
||||
for p in paths if p.is_file()]
|
||||
require(files, 'Empty seal forbidden')
|
||||
save(directory/'manifest.json', dict(root=str(directory), files=files))
|
||||
with (directory/'checksums.sha256').open('x', encoding='utf-8', newline='\n') as out:
|
||||
for row in files:
|
||||
out.write(row['sha256']+' '+row['path']+'\n')
|
||||
out.write(digest(directory/'manifest.json')+' manifest.json\n')
|
||||
return helper().verify_seal(directory)
|
||||
|
||||
|
||||
def finalize(reg_sha, numerical_sha, budget_sha, integrity_sha):
|
||||
require(sys.dont_write_bytecode and 'torch' not in sys.modules, 'Fresh CPU -B process required')
|
||||
require(not any((EXP/n).exists() for n in ('audit/final-status.json', 'manifest.json', 'checksums.sha256', 'audit/stopped.json')),
|
||||
'Stopped, finalized or partly sealed workflow requires a separate explicit failure audit')
|
||||
reg_path = EXP/'protocol/preregistered.json'
|
||||
require(digest(reg_path) == reg_sha, 'External registration changed')
|
||||
reg = read(reg_path)
|
||||
require(reg['schema'] == 'conditioning-execution-registration-v1' and reg['engineering_only'] is True and
|
||||
reg['scientific_acquisition_authorized'] is False, 'Wrong scope')
|
||||
verify({**reg['source_sha256'], **reg['input_sha256'], **reg['prepared_file_sha256']})
|
||||
reports = {}
|
||||
for key, relative, sha in (
|
||||
('numerical', 'audit/numerical-comparison.json', numerical_sha),
|
||||
('budget', 'audit/budget-report.json', budget_sha),
|
||||
('integrity', 'regression/integrity-after.json', integrity_sha)):
|
||||
path = EXP/relative
|
||||
require(A.pin(path)['sha256'] == sha, 'External '+key+' report changed')
|
||||
reports[key] = read(path)
|
||||
numerical, budget, integrity = (reports[n] for n in ('numerical', 'budget', 'integrity'))
|
||||
require(numerical['schema'] == 'conditioning-execution-numerical-audit-v1' and numerical['complete'] is True and
|
||||
numerical['registration_sha256'] == reg_sha and numerical['actual_new_brain_calls'] == 23 and
|
||||
numerical['actual_processes'] == 31 and numerical['actual_new_brain_ticks'] == 125200 and
|
||||
numerical['learning_pass_claimed'] is numerical['candidate_generated'] is False, 'Wrong numerical coverage/scope')
|
||||
status = numerical['status']
|
||||
require(status in ('PASS-EXACT-UPDATED-BOUNDARY-ENGINEERING-NOT-LEARNING',
|
||||
'FAIL-NUMERICAL-OR-LINEAGE', 'INCOMPLETE-CHANGED-EDGE-COVERAGE'), 'Unknown engineering outcome')
|
||||
require(numerical['pass_all'] == status.startswith('PASS-'), 'Inconsistent engineering gate')
|
||||
require(budget['registration_sha256'] == reg_sha and budget['learning_pass_claimed'] is False,
|
||||
'Wrong budget authority or scientific overclaim')
|
||||
require(integrity['complete'] is True and integrity['AP']['pass_all'] is True and
|
||||
integrity['old_experiments_reexecuted'] is integrity['old_files_modified'] is False and
|
||||
integrity['five_frozen_reference_trials_rerun_here'] is integrity['scientific_learning_pass_claimed'] is False,
|
||||
'Historical integrity/scope not verified')
|
||||
# Recheck the actual file-bound evidence at sealing, not only old PASS flags.
|
||||
import audit_execution
|
||||
import budget_report
|
||||
require(audit_execution.same_json(audit_execution.audit(reg_sha, save_report=False), numerical),
|
||||
'Numerical evidence changed after the independent audit')
|
||||
require(audit_execution.same_json(budget_report.report(reg_sha, save_report=False), budget),
|
||||
'Budget evidence changed after the independent audit')
|
||||
# Historical integrity has a different frozen runtime import owner; isolate it.
|
||||
seal_integrity = EXP/'regression/integrity-at-seal.json'
|
||||
require(not seal_integrity.exists(), 'No automatic retry of partly completed finalization')
|
||||
command = [sys.executable, '-B', str(MODEL/'prepare_execution.py'), 'integrity', '--output', str(seal_integrity)]
|
||||
result = subprocess.run(command, cwd=MODEL, capture_output=True, text=True, timeout=1800)
|
||||
require(result.returncode == 0 and seal_integrity.is_file(),
|
||||
'Independent integrity-at-seal process failed: '+result.stderr[-2000:])
|
||||
require(audit_execution.same_json(read(seal_integrity), integrity), 'Frozen integrity changed before sealing')
|
||||
final = dict(schema='conditioning-execution-final-v1', status=status, registration_sha256=reg_sha,
|
||||
numerical_sha256=numerical_sha, budget_sha256=budget_sha, integrity_after_sha256=integrity_sha,
|
||||
integrity_at_seal_sha256=digest(seal_integrity), numerical_and_budget_recomputed_at_seal=True,
|
||||
actual_new_brain_calls=23, actual_new_brain_ticks=125200, actual_execution_child_processes=31,
|
||||
historical_integrity_after_pass=True, historical_five_trial_regression='AM sealed evidence preserved; not rerun here',
|
||||
scientific_acquisition_executed=False, scientific_acquisition_authorized=False,
|
||||
candidate_generated=False, learning_pass_claimed=False,
|
||||
source_code_commit=reg['source_code_commit'], entire_model_directory_sealed=False,
|
||||
source_scope='All registered source bytes and committed snapshot frozen by this experiment seal',
|
||||
bulk_data_git_backup_claimed=False)
|
||||
save(EXP/'audit/final-status.json', final)
|
||||
checked = seal(EXP)
|
||||
return dict(status=status, manifest_sha256=checked['manifest_sha256'], checksums_sha256=checked['checksums_sha256'],
|
||||
final_sha256=digest(EXP/'audit/final-status.json'), payload_files=checked['payload_file_count'],
|
||||
payload_bytes=checked['payload_bytes'], learning_pass_claimed=False)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
for name in ('registration', 'numerical', 'budget', 'integrity'):
|
||||
parser.add_argument('--'+name+'-sha256', required=True)
|
||||
args = parser.parse_args()
|
||||
print(json.dumps(finalize(args.registration_sha256, args.numerical_sha256, args.budget_sha256,
|
||||
args.integrity_sha256), sort_keys=True), flush=True)
|
||||
@@ -0,0 +1,240 @@
|
||||
"""Fresh exec workers for the NEW boundary-validation branch, not learning.
|
||||
|
||||
The unchanged AP worker supplies read-only path/hash/environment helpers.
|
||||
One worker imports exactly one new scientific entry point. The process parent
|
||||
must authenticate registration, record actual exit status and independently
|
||||
check the result. A worker receipt cannot prove its own future successful exit.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
from datetime import datetime, timezone
|
||||
import hashlib
|
||||
import importlib.util
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import sys
|
||||
import time
|
||||
|
||||
AP_SHA = 'e47651a8ea99d7c44115107ff6b5dc71312183609ae11c891db65bb21ed61e30'
|
||||
MODEL = Path(__file__).resolve().parent
|
||||
AP = MODEL.parent / 'conditioning-interface-v2' / 'isolated_workers.py'
|
||||
SCHEMA = 'conditioning-isolated-execution-job-v1'
|
||||
C_PATH = MODEL.parent/'olfactory-conditioning-lab-v1/runtime_continuation.py'
|
||||
C_SHA = '0b8e8e0a6a23a079dc62a88355ce355d53b3ae22f6665519a8f6aef2dcfc5aba'
|
||||
COMMON = {'schema', 'job_id', 'kind', 'registration_sha256', 'worker_sha256',
|
||||
'source_sha256', 'input_sha256', 'output_dir', 'receipt_file', 'budget'}
|
||||
FIELDS = {
|
||||
'updated': {'authority_file', 'authority_sha256', 'build_root', 'diagnostic_mode'},
|
||||
'oracle': {'authority_file', 'authority_sha256', 'build_root', 'oracle_case',
|
||||
'oracle_spec_sha256', 'oracle_requests_sha256'},
|
||||
'validate_cpu': {'authority_file', 'authority_sha256', 'update_dir', 'chain_sha256'},
|
||||
'unchanged': {'authority_file', 'authority_sha256', 'case_dir', 'build_root', 'diagnostic_mode',
|
||||
'overlay_file', 'overlay_manifest', 'checkpoint_dir', 'checkpoint_sha256'},
|
||||
'sample': {'authority_file', 'authority_sha256'},
|
||||
}
|
||||
SOURCES = {
|
||||
'updated': {'updated_continuation.py'},
|
||||
'oracle': {'updated_continuation.py', 'boundary_oracle.py'},
|
||||
'validate_cpu': {'validate_update_cpu.py'},
|
||||
'unchanged': set(),
|
||||
'sample': {'boundary_sampler.py','boundary_plan.py'},
|
||||
}
|
||||
|
||||
|
||||
def ap_helpers():
|
||||
raw = AP.read_bytes()
|
||||
if hashlib.sha256(raw).hexdigest() != AP_SHA:
|
||||
raise ValueError('Frozen AP helper SHA differs')
|
||||
name = '_conditioning_execution_AP_helpers'
|
||||
if name in sys.modules:
|
||||
raise ValueError('Fresh exec helper binding required')
|
||||
spec = importlib.util.spec_from_file_location(name, AP)
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
sys.modules[name] = module
|
||||
exec(compile(raw, str(AP), 'exec'), module.__dict__)
|
||||
return module
|
||||
|
||||
|
||||
def validate_job(h, job_file, expected_sha):
|
||||
job_file = h.absolute_path(str(job_file), kind='file')
|
||||
h.require(h.valid_sha(expected_sha) and h.digest(job_file) == expected_sha, 'External job pin differs')
|
||||
job = h.read_json(job_file)
|
||||
kind = job.get('kind')
|
||||
h.require(kind in FIELDS and set(job) == COMMON | FIELDS[kind] and job['schema'] == SCHEMA,
|
||||
'Wrong job schema/fields')
|
||||
h.require(type(job['job_id']) is str and job['job_id'] and
|
||||
all(c.isascii() and (c.isalnum() or c in '-_') for c in job['job_id']), 'Unsafe job ID')
|
||||
h.require(h.valid_sha(job['registration_sha256']) and job['worker_sha256'] == h.digest(__file__),
|
||||
'Missing registration/worker binding')
|
||||
h.require(type(job['source_sha256']) is dict and set(job['source_sha256']) == SOURCES[kind] and
|
||||
type(job['input_sha256']) is dict and job['input_sha256'], 'Wrong source/input inventory')
|
||||
pins = {job_file: expected_sha, Path(__file__).resolve(): job['worker_sha256'], AP: AP_SHA}
|
||||
for path, sha in job['input_sha256'].items():
|
||||
h._put(pins, h.absolute_path(path, kind='file'), sha)
|
||||
for name, sha in job['source_sha256'].items():
|
||||
h._put(pins, h.absolute_path(str(MODEL / name), kind='file'), sha)
|
||||
authority = h.absolute_path(job['authority_file'], kind='file')
|
||||
h._required(pins, authority, job['authority_sha256'])
|
||||
if kind=='sample':
|
||||
h.require(job['authority_sha256']==job['registration_sha256'],'Sampler registration and authority differ')
|
||||
registered=h.read_json(authority)
|
||||
h.require(registered.get('schema')=='conditioning-execution-registration-v1','Wrong sampler registration')
|
||||
for field in ('source_sha256','input_sha256','prepared_file_sha256'):
|
||||
for path,sha in registered[field].items():h._required(pins,path,sha)
|
||||
output, receipt = (h.absolute_path(job[name]) for name in ('output_dir', 'receipt_file'))
|
||||
attempt = Path(str(receipt) + '.attempt.json')
|
||||
h.require(output.parent.is_dir() and receipt.parent.is_dir() and
|
||||
not any(p.exists() for p in (output, receipt, attempt)), 'Output/receipt exists; no automatic retry')
|
||||
protected = {p.parent for p in pins}
|
||||
h.require(not any(output.is_relative_to(p) or receipt.is_relative_to(p) for p in protected) and
|
||||
not receipt.is_relative_to(output) and not output.is_relative_to(receipt.parent),
|
||||
'Output/receipt overlaps protected input or each other')
|
||||
paths = dict(job=job_file, authority=authority, output=output, receipt=receipt, attempt=attempt)
|
||||
if kind in ('updated', 'oracle', 'unchanged'):
|
||||
build = h.absolute_path(job['build_root'])
|
||||
h.require(not any(build.is_relative_to(p) for p in protected) and not build.is_relative_to(output) and
|
||||
not output.is_relative_to(build), 'Build overlaps protected data')
|
||||
paths['build'] = build
|
||||
if kind in ('updated', 'unchanged'):
|
||||
h.require(job['diagnostic_mode'] in ('light', 'reference'), 'Unknown diagnostic mode')
|
||||
if kind == 'unchanged':
|
||||
h._required(pins, C_PATH, C_SHA)
|
||||
paths['case'] = h.absolute_path(job['case_dir'], kind='dir')
|
||||
paths['checkpoint'] = h.absolute_path(job['checkpoint_dir'], kind='dir')
|
||||
h._required(pins, paths['checkpoint']/'checkpoint-manifest.json', job['checkpoint_sha256'])
|
||||
for role in ('overlay_file', 'overlay_manifest'):
|
||||
paths[role] = h._required(pins, job[role])
|
||||
for name in ('spec.json', 'requests.npz'): h._required(pins, paths['case']/name)
|
||||
h.require(not output.is_relative_to(paths['checkpoint']) and not paths['build'].is_relative_to(paths['checkpoint']),
|
||||
'Execution overlaps frozen parent')
|
||||
elif kind == 'oracle':
|
||||
paths['case'] = h.absolute_path(job['oracle_case'], kind='dir')
|
||||
for name, key in (('spec.json', 'oracle_spec_sha256'), ('requests.npz', 'oracle_requests_sha256')):
|
||||
h._required(pins, paths['case'] / name, job[key])
|
||||
elif kind == 'validate_cpu':
|
||||
paths['update'] = h.absolute_path(job['update_dir'], kind='dir')
|
||||
h._required(pins, paths['update'] / 'chain-receipt.json', job['chain_sha256'])
|
||||
h.require(not output.is_relative_to(paths['update']), 'CPU receipt overlaps source update')
|
||||
budget = job['budget']
|
||||
h.require(type(budget) is dict and set(budget) == {'root', 'output_cap_bytes', 'minimum_free_reserve_bytes'},
|
||||
'Explicit bounded resource plan required')
|
||||
paths['budget'] = h.absolute_path(budget['root'], kind='dir')
|
||||
h.require(paths['budget'].name.startswith('phase4') and output.is_relative_to(paths['budget']) and
|
||||
receipt.is_relative_to(paths['budget']) and
|
||||
(kind in ('validate_cpu','sample') or paths['build'].is_relative_to(paths['budget'])), 'Execution leaves assigned experiment')
|
||||
for name in ('output_cap_bytes', 'minimum_free_reserve_bytes'):
|
||||
h.require(type(budget[name]) is int and budget[name] > 0, 'Positive resource limit required')
|
||||
h.verify_pins(pins)
|
||||
return job, paths, pins
|
||||
|
||||
|
||||
def budget_check(h, job, paths):
|
||||
used = 0
|
||||
for path in paths['budget'].rglob('*'):
|
||||
h.require(not path.is_symlink(), 'Linked output forbidden')
|
||||
if path.is_file():
|
||||
used += path.stat().st_size
|
||||
else:
|
||||
h.require(path.is_dir(), 'Nonregular output forbidden')
|
||||
cap = job['budget']['output_cap_bytes']
|
||||
free = shutil.disk_usage(paths['budget']).free
|
||||
h.require(used <= cap and free >= job['budget']['minimum_free_reserve_bytes'] + max(0, cap - used),
|
||||
'Resource budget exceeded; do not change protocol or retry')
|
||||
return dict(output_bytes=used, free_bytes=free, output_cap_bytes=cap)
|
||||
|
||||
|
||||
def bind_unchanged_authority(h, job, paths, pins):
|
||||
admitted=h.read_json(paths['authority'])
|
||||
h.require(admitted.get('schema')=='conditioning-updated-boundary-v1' and admitted.get('transition')=='epoch_update' and
|
||||
admitted['diagnostic_mode']==job['diagnostic_mode'] and admitted['registration_sha256']==job['registration_sha256'] and
|
||||
admitted['expected_effective_weight_before_sha256']==admitted['expected_effective_weight_after_sha256'],
|
||||
'Old C comparison requires its unchanged-weight registered authority')
|
||||
h.require(admitted['parent']==dict(directory=str(paths['checkpoint']),checkpoint_manifest_sha256=job['checkpoint_sha256']),
|
||||
'Old C job parent differs from authority')
|
||||
for pair,role in ((admitted['case']['spec'],'spec.json'),(admitted['case']['requests'],'requests.npz')):
|
||||
h.require(pair['path']==str(paths['case']/role) and pins[paths['case']/role]==pair['sha256'],
|
||||
'Old C case differs from authority')
|
||||
for role,key in (('file','overlay_file'),('manifest','overlay_manifest')):
|
||||
pair=admitted['overlay_before'][role]
|
||||
h.require(pair['path']==str(paths[key]) and pins[paths[key]]==pair['sha256'],
|
||||
'Old C must use actual before snapshot, not equal after data')
|
||||
def visit(value):
|
||||
if type(value)is dict:
|
||||
if set(value)=={'path','sha256'}:h._required(pins,value['path'],value['sha256'])
|
||||
else:
|
||||
for key,item in value.items():
|
||||
if key=='frozen_inputs':
|
||||
for path,sha in item.items():h._required(pins,path,sha)
|
||||
else:visit(item)
|
||||
elif type(value)is list:
|
||||
for item in value:visit(item)
|
||||
visit(admitted)
|
||||
return admitted
|
||||
|
||||
|
||||
def execute(job_file, expected_sha):
|
||||
started = time.perf_counter()
|
||||
h = ap_helpers()
|
||||
h.require(sys.dont_write_bytecode, 'Use Python -B')
|
||||
job, paths, pins = validate_job(h, job_file, expected_sha)
|
||||
kind = job['kind']
|
||||
h._clean_process('update' if kind == 'validate_cpu' else 'brain')
|
||||
before = budget_check(h, job, paths)
|
||||
h.save_json(paths['attempt'], dict(schema='conditioning-execution-attempt-v1', complete=False,
|
||||
job_sha256=expected_sha, pid=os.getpid(), started_utc=datetime.now(timezone.utc).isoformat(),
|
||||
no_automatic_retry=True))
|
||||
admission = None if kind == 'validate_cpu' else h._admit_brain()
|
||||
if kind == 'unchanged':
|
||||
module = h._load_source('_conditioning_execution_entry', C_PATH, C_SHA)
|
||||
bind_unchanged_authority(h, job, paths, pins)
|
||||
result = module.run_continued(paths['case'], paths['output'], paths['build'], paths['overlay_file'],
|
||||
paths['overlay_manifest'], paths['checkpoint'], mode=job['diagnostic_mode'])
|
||||
checked = module.load_checkpoint(paths['output'], result['checkpoint_manifest_sha256'])
|
||||
h.require(checked['summary'] == {k:v for k,v in result.items() if k!='checkpoint_manifest_sha256'},
|
||||
'Original C returned checkpoint differs')
|
||||
else:
|
||||
entry = {'updated': 'updated_continuation.py', 'oracle': 'boundary_oracle.py',
|
||||
'validate_cpu': 'validate_update_cpu.py', 'sample': 'boundary_sampler.py'}[kind]
|
||||
module = h._load_source('_conditioning_execution_entry', MODEL / entry, job['source_sha256'][entry])
|
||||
if kind == 'updated':
|
||||
result = module.run(paths['authority'], job['authority_sha256'], paths['output'], paths['build'],
|
||||
mode=job['diagnostic_mode'])
|
||||
elif kind == 'oracle':
|
||||
result = module.run(paths['authority'], job['authority_sha256'], job['source_sha256']['updated_continuation.py'],
|
||||
paths['case'], job['oracle_spec_sha256'], job['oracle_requests_sha256'], paths['output'], paths['build'])
|
||||
elif kind == 'validate_cpu':
|
||||
paths['output'].mkdir()
|
||||
result = module.validate(paths['authority'], job['authority_sha256'], paths['update'],
|
||||
job['chain_sha256'], paths['output'] / 'validation.json')
|
||||
elif kind == 'sample':
|
||||
result = module.run(paths['authority'], job['authority_sha256'], paths['output'])
|
||||
environment = h._environment('update' if kind == 'validate_cpu' else 'brain')
|
||||
if kind not in ('validate_cpu','sample'):
|
||||
h._verify_precision(environment, result['apl_component']['environment'])
|
||||
outputs = h.tree_hashes(paths['output'])
|
||||
h.verify_pins(pins)
|
||||
after = budget_check(h, job, paths)
|
||||
h.require(outputs == h.tree_hashes(paths['output']), 'Outputs changed during verification')
|
||||
receipt = dict(schema='conditioning-isolated-execution-receipt-v1', complete=True,
|
||||
job_id=job['job_id'], kind=kind, registration_sha256=job['registration_sha256'], job_sha256=expected_sha,
|
||||
worker_sha256=job['worker_sha256'], attempt_sha256=h.digest(paths['attempt']),
|
||||
input_sha256={str(p): sha for p, sha in pins.items()}, output_files_sha256=outputs,
|
||||
output_dir=str(paths['output']), result=result, environment=environment, admission=admission,
|
||||
resource_before=before, resource_after=after, wall_seconds=time.perf_counter()-started,
|
||||
wall_scope='entry through verification; parent separately measures spawn/exit/parent validation',
|
||||
process_exit_independently_observed=False, registration_authority_independently_proven=False,
|
||||
scientific_learning_pass_claimed=False, candidate_generated=False, old_source_globals_patched=False)
|
||||
h.save_json(paths['receipt'], receipt)
|
||||
return receipt
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--job', required=True)
|
||||
parser.add_argument('--job-sha256', required=True)
|
||||
args = parser.parse_args()
|
||||
receipt = execute(args.job, args.job_sha256)
|
||||
print(json.dumps(dict(complete=True, job_id=receipt['job_id'], kind=receipt['kind'])), flush=True)
|
||||
@@ -0,0 +1,562 @@
|
||||
"""Pure, pre-registration conditioning gates; never an execution authority.
|
||||
|
||||
The numeric rules come from PROTOCOL_DRAFT sections 6-8 and the fixed
|
||||
EVALUATION_POLICY_DRAFT. Two explicit pre-outcome operationalizations require
|
||||
the caller's policy descriptor: reversal/retention downstream means the exact
|
||||
nonMBONDownstream set, with legacyDownstream also reported; the old H mean
|
||||
predicate is evaluated twice per (mode, original cue), using each DAN branch's
|
||||
own complete control vectors, and both results must pass that separate audit.
|
||||
Neither choice is described as the original H data layout.
|
||||
|
||||
All evaluation functions are CPU/pure: descriptors and raw arrays are checked,
|
||||
but disk receipts, anatomical identities, seed derivation, actual execution,
|
||||
registration authority and full numerical/integrity audits remain EXTERNAL.
|
||||
A supplied SHA or Boolean is not proof of any of those facts. Consequently no
|
||||
return value claims scientific learning, execution approval or a candidate.
|
||||
The only file read is the pinned Python dependency at module import time.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
from collections.abc import Mapping
|
||||
from pathlib import Path
|
||||
import types
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
||||
METRICS_SHA256 = '47319e21db3c8b030b1bafbf0703cd86fb588d23bb29436accbacdba73d08c3c'
|
||||
_path = Path(__file__).resolve().parent.parent / 'olfactory-conditioning-lab-v1' / 'metrics.py'
|
||||
_source = _path.read_bytes()
|
||||
if hashlib.sha256(_source).hexdigest() != METRICS_SHA256:
|
||||
raise ValueError('Frozen metrics source SHA256 differs')
|
||||
M = types.ModuleType('conditioning_execution_frozen_metrics')
|
||||
M.__file__ = str(_path)
|
||||
exec(compile(_source, str(_path), 'exec'), M.__dict__)
|
||||
del _source
|
||||
|
||||
SCHEMA = 'conditioning-learning-gates-v1'
|
||||
REGISTRY_SCHEMA = 'conditioning-gate-registry-descriptor-v1'
|
||||
AUTHORITY_SCHEMA = 'conditioning-data-authority-descriptor-v1'
|
||||
PAIR_SCHEMA = 'conditioning-probe-pair-descriptor-v1'
|
||||
DOWNSTREAM_POLICY = 'nonMBONDownstream-pre-outcome-operationalization-v1'
|
||||
H_MAPPING = 'each-DAN-control-source-separately-both-pass-v1'
|
||||
ASSAYS = ('normal', 'delayed', 'reversal', 'retention')
|
||||
DAN_COMPARTMENTS = {'PAM15': "y5B'2a", 'PPL103': "y2a'1"}
|
||||
CARRY = ('v', 'g', 'ref', 'spike_ring', 'apl_state', 'apl_pending', 'absolute_tick', 'delta', 'relevant_rng_state')
|
||||
EXTERNAL = ('registration/source authority', 'anatomical membership', 'full seed derivation and alias inventory',
|
||||
'actual input/receipt files and completed trajectories', 'continuous state/queue/RNG restoration',
|
||||
'full finite/integrity/resource audits')
|
||||
|
||||
|
||||
def require(ok, message):
|
||||
if not ok:
|
||||
raise ValueError(message)
|
||||
|
||||
|
||||
def _keys(value, fields, label):
|
||||
require(isinstance(value, Mapping) and set(value) == set(fields), 'Wrong ' + label + ' fields')
|
||||
|
||||
|
||||
def _sha(value, label):
|
||||
require(M._sha(value), 'Invalid SHA256: ' + label)
|
||||
return value
|
||||
|
||||
|
||||
def _token(value, label):
|
||||
return M._token(value, label)
|
||||
|
||||
|
||||
def descriptor_sha256(value):
|
||||
"""Canonical descriptor hash; this does NOT establish external authority."""
|
||||
return hashlib.sha256(json.dumps(value, sort_keys=True, separators=(',', ':'),
|
||||
ensure_ascii=False, allow_nan=False).encode('utf-8')).hexdigest()
|
||||
|
||||
|
||||
def _scope():
|
||||
return dict(external_authority_verified=False, scientific_learning_pass_claimed=False,
|
||||
candidate_generated=False, execution_authorized=False, data_backed_claimed=False,
|
||||
external_requirements=list(EXTERNAL), frozen_metrics_source_sha256=METRICS_SHA256)
|
||||
|
||||
|
||||
def validate_registry(registry, *, expected_sha256):
|
||||
"""Check all 40 declared blocks and actual 63-bit seeds, never just labels.
|
||||
|
||||
training_sources lists independent training/design source streams, excluding
|
||||
counterfactual aliases. The external registrar must prove that this list is
|
||||
complete and agrees with the frozen full trial/seed inventory. Evaluation is
|
||||
one original A/B input pair per block, reused within that block across assays.
|
||||
"""
|
||||
_keys(registry, ('schema', 'protocol_sha256', 'population_binding_sha256',
|
||||
'nodes_raw_sha256', 'population_membership_sha256', 'blocks'), 'registry')
|
||||
require(registry['schema'] == REGISTRY_SCHEMA, 'Wrong registry schema')
|
||||
require(descriptor_sha256(registry) == _sha(expected_sha256, 'external registry'), 'Registry descriptor changed')
|
||||
for field in ('protocol_sha256', 'population_binding_sha256', 'nodes_raw_sha256', 'population_membership_sha256'):
|
||||
_sha(registry[field], field)
|
||||
require(isinstance(registry['blocks'], Mapping) and len(registry['blocks']) == 40, 'Exactly 40 registered blocks required')
|
||||
identities, streams, seeds = set(), set(), set()
|
||||
for block_id, block in registry['blocks'].items():
|
||||
_token(block_id, 'block_id')
|
||||
_keys(block, ('mode', 'dan_type', 'compartment_verbatim', 'conditioned_cue', 'replicate',
|
||||
'training_sources', 'evaluation_sources', 'evaluation_input_sha256'), 'block')
|
||||
require(block['mode'] in M.MODES and block['dan_type'] in DAN_COMPARTMENTS and
|
||||
block['compartment_verbatim'] == DAN_COMPARTMENTS[block['dan_type']] and
|
||||
block['conditioned_cue'] in M.CUES and type(block['replicate']) is int and 1 <= block['replicate'] <= 5,
|
||||
'Unknown cell/compartment/replicate')
|
||||
identity = (block['mode'], block['dan_type'], block['conditioned_cue'], block['replicate'])
|
||||
require(identity not in identities, 'Duplicate cell/replicate')
|
||||
identities.add(identity)
|
||||
require(type(block['training_sources']) is list and block['training_sources'], 'Missing independent training/design sources')
|
||||
_keys(block['evaluation_sources'], M.CUES, 'evaluation sources')
|
||||
_keys(block['evaluation_input_sha256'], M.CUES, 'evaluation input hashes')
|
||||
for cue in M.CUES:
|
||||
_sha(block['evaluation_input_sha256'][cue], 'evaluation input')
|
||||
entries = [(x, ('training', 'design')) for x in block['training_sources']]
|
||||
entries += [(block['evaluation_sources'][cue], ('evaluation',)) for cue in M.CUES]
|
||||
for source, allowed in entries:
|
||||
_keys(source, ('stream_id', 'seed', 'split'), 'independent source')
|
||||
_token(source['stream_id'], 'stream_id')
|
||||
require(source['split'] in allowed and type(source['seed']) is int and 0 <= source['seed'] < 2**63,
|
||||
'Wrong source split or full63bit seed')
|
||||
require(source['stream_id'] not in streams and source['seed'] not in seeds,
|
||||
'Independent source ID/seed collision, including training/evaluation overlap')
|
||||
streams.add(source['stream_id']); seeds.add(source['seed'])
|
||||
require(len(identities) == 40, 'Incomplete eight-cell/five-replicate inventory')
|
||||
return dict(schema=SCHEMA, registry_sha256=expected_sha256, blocks=40,
|
||||
independent_declared_streams=len(streams), **_scope())
|
||||
|
||||
|
||||
def _context(registry, authority, nodes=None, populations=None):
|
||||
_keys(authority, ('schema', 'registry_sha256', 'verification_receipt_sha256',
|
||||
'execution_inventory_sha256', 'population_binding_sha256'), 'external data authority descriptor')
|
||||
require(authority['schema'] == AUTHORITY_SCHEMA, 'Wrong data authority schema')
|
||||
for field in ('registry_sha256', 'verification_receipt_sha256', 'execution_inventory_sha256', 'population_binding_sha256'):
|
||||
_sha(authority[field], field)
|
||||
validate_registry(registry, expected_sha256=authority['registry_sha256'])
|
||||
require(authority['population_binding_sha256'] == registry['population_binding_sha256'], 'Population authority binding differs')
|
||||
if nodes is not None:
|
||||
membership = M.validate_populations(nodes, populations)
|
||||
require(M._hash(nodes) == registry['nodes_raw_sha256'] and
|
||||
membership['membership_sha256'] == registry['population_membership_sha256'], 'Raw population binding differs')
|
||||
|
||||
|
||||
def _cell_rows(rows, registry, mode, dan_type, conditioned_cue):
|
||||
require(mode in M.MODES and dan_type in DAN_COMPARTMENTS and conditioned_cue in M.CUES, 'Unknown cell')
|
||||
require(type(rows) is list and len(rows) == 5, 'Exactly five independent training rows required')
|
||||
expected = {key for key, value in registry['blocks'].items()
|
||||
if (value['mode'], value['dan_type'], value['conditioned_cue']) == (mode, dan_type, conditioned_cue)}
|
||||
require(len(expected) == 5 and {row['replicate_id'] for row in rows} == expected, 'Missing/duplicate/wrong-cell training rows')
|
||||
for row in rows:
|
||||
block = registry['blocks'][row['replicate_id']]
|
||||
require(row['replicate_unit'] == 'independent_training', 'Evaluation draws are not training replicates')
|
||||
require(row['training_stream_ids'] == [x['stream_id'] for x in block['training_sources']], 'Training source lineage differs')
|
||||
require(row['evaluation_stream_ids'] == [block['evaluation_sources'][cue]['stream_id'] for cue in M.CUES],
|
||||
'Both registered evaluation inputs required; no extra evaluation replication')
|
||||
return expected
|
||||
|
||||
|
||||
def _pair(pair, block_id, registry, nodes, populations, used, *, policy, delta=None, checkpoint=None):
|
||||
fields = ('schema', 'block_id', 'snapshot_id', 'receipt_sha256', 'probe_receipt_sha256',
|
||||
'evaluation_input_sha256', 'state_raw_sha256', 'states', 'state_policy', 'source_checkpoint_sha256',
|
||||
'delta_sha256', 'probe_steps', 'cs_start_tick', 'cs_stop_tick_exclusive', 'US_requested',
|
||||
'weight_updates_enabled', 'feedback_to_training_or_idle')
|
||||
_keys(pair, fields, 'probe pair')
|
||||
require(pair['schema'] == PAIR_SCHEMA and pair['block_id'] == block_id and pair['state_policy'] == policy,
|
||||
'Probe identity/state policy differs')
|
||||
_token(pair['snapshot_id'], 'snapshot_id')
|
||||
for field in ('receipt_sha256', 'source_checkpoint_sha256', 'delta_sha256'):
|
||||
_sha(pair[field], field)
|
||||
require(type(pair['probe_steps']) is int and pair['probe_steps'] == 1200 and
|
||||
type(pair['cs_start_tick']) is int and pair['cs_start_tick'] == 0 and
|
||||
type(pair['cs_stop_tick_exclusive']) is int and pair['cs_stop_tick_exclusive'] == 1000 and
|
||||
pair['US_requested'] is False and pair['weight_updates_enabled'] is False and
|
||||
pair['feedback_to_training_or_idle'] is False, 'Probe timing/US/update/feedback differs')
|
||||
require(delta is None or pair['delta_sha256'] == delta, 'Probe delta source differs')
|
||||
require(checkpoint is None or pair['source_checkpoint_sha256'] == checkpoint, 'Probe checkpoint source differs')
|
||||
for field in ('probe_receipt_sha256', 'evaluation_input_sha256', 'state_raw_sha256', 'states'):
|
||||
_keys(pair[field], M.CUES, field)
|
||||
require(pair['evaluation_input_sha256'] == registry['blocks'][block_id]['evaluation_input_sha256'],
|
||||
'Probe must use the exact registered evaluation inputs')
|
||||
for cue in M.CUES:
|
||||
_sha(pair['probe_receipt_sha256'][cue], 'probe receipt')
|
||||
checked = M.validate_state(pair['states'][cue], nodes=nodes, steps=1200)
|
||||
require(pair['state_raw_sha256'][cue] == checked['hashes'], 'Probe raw arrays differ from descriptor hashes')
|
||||
# Re-referencing one baseline is permitted, but a new snapshot cannot claim
|
||||
# that it executed a probe by reusing another snapshot's receipt.
|
||||
fingerprint = descriptor_sha256({key: value for key, value in pair.items() if key != 'states'})
|
||||
identity = pair['snapshot_id']
|
||||
require(identity not in used['snapshots'] or used['snapshots'][identity] == fingerprint, 'Snapshot identity reused with changed data')
|
||||
for receipt in (pair['receipt_sha256'], *pair['probe_receipt_sha256'].values()):
|
||||
require(receipt not in used['receipts'] or used['receipts'][receipt] == identity, 'Probe execution receipt reused across snapshots')
|
||||
used['receipts'][receipt] = identity
|
||||
require(len({pair['receipt_sha256'], *pair['probe_receipt_sha256'].values()}) == 3, 'A/B probes require distinct actual receipts')
|
||||
used['snapshots'][identity] = fingerprint
|
||||
return pair['states']
|
||||
|
||||
|
||||
def _arm_execution(value, *, assay, arm, used):
|
||||
_keys(value, ('receipt_sha256', 'recording_verified', 'complete', 'completed_epochs',
|
||||
'reinforcement_opportunities', 'terminal_pairings', 'epoch_duration_ms', 'cs_duration_ms', 'us_tick',
|
||||
'initial_delta_sha256', 'terminal_delta_sha256', 'terminal_checkpoint_sha256',
|
||||
'neural_state_policy', 'weight_rule', 'reinforced_cue'), 'training execution descriptor')
|
||||
for key in ('receipt_sha256', 'initial_delta_sha256', 'terminal_delta_sha256', 'terminal_checkpoint_sha256'):
|
||||
_sha(value[key], key)
|
||||
require(value['receipt_sha256'] not in used, 'Training receipt reused across arms/replicates')
|
||||
used.add(value['receipt_sha256'])
|
||||
require(value['complete'] is True and value['recording_verified'] is True,
|
||||
'Caller must supply a completed, externally verified execution descriptor')
|
||||
for field, expected in (('completed_epochs', 150 if arm == 'unpaired' else 100),
|
||||
('reinforcement_opportunities', 0 if arm == 'CS-only' else 50), ('terminal_pairings', 50),
|
||||
('us_tick', 1500 if assay == 'delayed' else 900)):
|
||||
require(type(value[field]) is int and value[field] == expected, 'Wrong terminal inventory: ' + field)
|
||||
require(value['epoch_duration_ms'] == (180. if assay == 'delayed' else 120.) and value['cs_duration_ms'] == 100. and
|
||||
value['neural_state_policy'] == 'fresh_epoch_delta_only' and value['weight_rule'] == 'frozen_temporal_eligibility_v2',
|
||||
'Frozen training timing/state/update policy differs')
|
||||
|
||||
|
||||
def _report(assay, rows, registry, authority, mode, dan_type, conditioned_cue):
|
||||
rows = sorted(rows, key=lambda row: row['replicate_id'])
|
||||
count = sum(row['conjunction_pass'] for row in rows)
|
||||
return dict(schema=SCHEMA, status='CONDITIONAL-PREDICATES-PASS' if count >= 3 else 'CONDITIONAL-PREDICATES-FAIL',
|
||||
assay=assay, mode=mode, dan_type=dan_type, conditioned_cue=conditioned_cue,
|
||||
predicate_pass=count >= 3, successful_same_replicate_conjunctions=count, required_majority=3,
|
||||
training_replicates=5, replicates=rows, registry_sha256=authority['registry_sha256'],
|
||||
external_data_authority_descriptor_sha256=descriptor_sha256(authority),
|
||||
downstream_policy=DOWNSTREAM_POLICY, policy_scope='pre-outcome additional operationalization', **_scope())
|
||||
|
||||
|
||||
def evaluate_acquisition(replicates, *, assay, mode, dan_type, conditioned_cue, registry, authority):
|
||||
"""Reuse the pinned normal/delayed gate, preserving every six-control rule.
|
||||
|
||||
replicates has the original frozen metrics schema. recording_verified is the
|
||||
external caller's descriptor assertion, NOT a verification done by this call.
|
||||
"""
|
||||
_context(registry, authority)
|
||||
_cell_rows(replicates, registry, mode, dan_type, conditioned_cue)
|
||||
registered = {row['replicate_id']: row['training_stream_ids'] for row in replicates}
|
||||
for row in replicates:
|
||||
for arm in row['arms'].values():
|
||||
for cue in M.CUES:
|
||||
summary = arm['metrics']['cues'][cue]
|
||||
require(summary['nodes_raw_sha256'] == registry['nodes_raw_sha256'] and
|
||||
summary['membership']['membership_sha256'] == registry['population_membership_sha256'], 'Population metric binding differs')
|
||||
frozen = M.evaluate_acquisition(replicates, assay=assay, mode=mode, dan_type=dan_type,
|
||||
conditioned_cue=conditioned_cue, registered_training_streams=registered)
|
||||
result = _report(assay, frozen['replicates'], registry, authority, mode, dan_type, conditioned_cue)
|
||||
result.update(frozen_acquisition_result=frozen, acquisition_controls=list(M.CONTROLS),
|
||||
downstream_policy='unchanged acquisition requires both legacyDownstream and nonMBONDownstream positive gains',
|
||||
acquisition_metric_inputs=json.loads(json.dumps(replicates, allow_nan=False)),
|
||||
legacy_control_MBON_gains={name: {row['replicate_id']: row['arms'][name]['metrics']['separation']['MBON']['gain']
|
||||
for row in replicates} for name in ('D=0', 'random reward', 'frozen')})
|
||||
return result
|
||||
|
||||
|
||||
def evaluate_reversal(replicates, *, mode, dan_type, conditioned_cue, registry, authority,
|
||||
nodes, populations, downstream_policy):
|
||||
"""Original pre/orientation, strict nonzero sign crossing, fixed 50 count."""
|
||||
require(downstream_policy == DOWNSTREAM_POLICY, 'Explicit preregistered downstream operationalization required')
|
||||
_context(registry, authority, nodes, populations)
|
||||
_cell_rows(replicates, registry, mode, dan_type, conditioned_cue)
|
||||
reports, execution_used = [], set()
|
||||
used = dict(snapshots={}, receipts={})
|
||||
neutral = next(cue for cue in M.CUES if cue != conditioned_cue)
|
||||
for row in replicates:
|
||||
_keys(row, ('replicate_id', 'replicate_unit', 'training_stream_ids', 'evaluation_stream_ids',
|
||||
'pre', 'acquisition', 'reversal', 'no_reversal', 'execution'), 'reversal row')
|
||||
block_id = row['replicate_id']
|
||||
_keys(row['execution'], ('acquisition', 'reversal', 'no_reversal'), 'reversal executions')
|
||||
for arm, execution in row['execution'].items():
|
||||
_arm_execution(execution, assay='normal', arm=arm, used=execution_used)
|
||||
require(execution['reinforced_cue'] == (neutral if arm == 'reversal' else conditioned_cue), 'Reversal cue assignment differs')
|
||||
acq = row['execution']['acquisition']
|
||||
for arm in ('reversal', 'no_reversal'):
|
||||
require(row['execution'][arm]['initial_delta_sha256'] == acq['terminal_delta_sha256'], 'Reversal must fork exact acquisition delta')
|
||||
pre = _pair(row['pre'], block_id, registry, nodes, populations, used, policy='common_frozen_reset', delta=acq['initial_delta_sha256'])
|
||||
metrics, states = {}, {}
|
||||
for arm in ('acquisition', 'reversal', 'no_reversal'):
|
||||
execution = row['execution'][arm]
|
||||
states[arm] = _pair(row[arm], block_id, registry, nodes, populations, used, policy='common_frozen_reset',
|
||||
delta=execution['terminal_delta_sha256'], checkpoint=execution['terminal_checkpoint_sha256'])
|
||||
metrics[arm] = M.arm_metrics(pre, states[arm], conditioned_cue=conditioned_cue, nodes=nodes, populations=populations)
|
||||
changes = {cue: M.functional_summary(states['acquisition'][cue], states['reversal'][cue],
|
||||
nodes=nodes, populations=populations, steps=1200) for cue in M.CUES}
|
||||
s = {arm: metric['rawS'] for arm, metric in metrics.items()}
|
||||
expected = (s['acquisition'] > 0 and s['no_reversal'] > 0 and s['reversal'] < 0) if dan_type == 'PAM15' else (
|
||||
s['acquisition'] < 0 and s['no_reversal'] < 0 and s['reversal'] > 0)
|
||||
mbon, down = (changes[neutral]['populations'][name] for name in ('MBON', 'nonMBONDownstream'))
|
||||
predicates = dict(strict_three_signed_relations=bool(expected),
|
||||
former_neutral_MBON_count_or_defined_first_latency=bool(mbon['spike_count_l1'] > 0 or mbon['defined_first_latency_changed']),
|
||||
former_neutral_nonMBONDownstream_event_or_count=bool(down['events_changed'] or down['spike_count_l1'] > 0))
|
||||
reports.append(dict(replicate_id=block_id, rawS=s, predicates=predicates, conjunction_pass=all(predicates.values()),
|
||||
metrics=metrics, acquisition_to_reversal_changes_by_cue=changes,
|
||||
legacy_style_sign_inequality_on_registered_S=bool(np.sign(s['acquisition']) != np.sign(s['reversal'])),
|
||||
exact_historical_H_readout_equivalence_claimed=False))
|
||||
return _report('reversal', reports, registry, authority, mode, dan_type, conditioned_cue)
|
||||
|
||||
|
||||
def _idle(branch, used, *, arm, conditioned_cue):
|
||||
_keys(branch, ('source_checkpoint_sha256', 'delta_sha256', 'idle_lineage_id', 'idle_receipt_sha256',
|
||||
'total_idle_ticks', 'no_input', 'updates_disabled', 'reset_state', 'analytic_time_advance',
|
||||
'one_second_is_prefix_of_ten_second', 'checkpoints', 'source_execution'), 'idle branch')
|
||||
_arm_execution(branch['source_execution'], assay='normal', arm=arm, used=used)
|
||||
source = branch['source_execution']
|
||||
require(source['terminal_checkpoint_sha256'] == branch['source_checkpoint_sha256'] and
|
||||
source['terminal_delta_sha256'] == branch['delta_sha256'] and source['reinforced_cue'] == conditioned_cue,
|
||||
'Idle source must bind the complete terminal normal paired/frozen execution')
|
||||
require(arm != 'frozen' or source['initial_delta_sha256'] == source['terminal_delta_sha256'],
|
||||
'Frozen training cannot change delta')
|
||||
for field in ('source_checkpoint_sha256', 'delta_sha256', 'idle_receipt_sha256'):
|
||||
_sha(branch[field], field)
|
||||
_token(branch['idle_lineage_id'], 'idle lineage')
|
||||
require(branch['idle_receipt_sha256'] not in used and branch['idle_lineage_id'] not in used, 'Idle branch/receipt reused')
|
||||
used.update((branch['idle_receipt_sha256'], branch['idle_lineage_id']))
|
||||
require(type(branch['total_idle_ticks']) is int and branch['total_idle_ticks'] == 100000 and
|
||||
branch['no_input'] is True and branch['updates_disabled'] is True and branch['reset_state'] is False and
|
||||
branch['analytic_time_advance'] is False and branch['one_second_is_prefix_of_ten_second'] is True,
|
||||
'Retention must be actual continuous 10-second idle with a 1-second prefix')
|
||||
_keys(branch['checkpoints'], ('0', '1', '10'), 'idle checkpoints')
|
||||
previous, start = None, None
|
||||
for second in (0, 1, 10):
|
||||
checkpoint = branch['checkpoints'][str(second)]
|
||||
_keys(checkpoint, ('checkpoint_sha256', 'parent_checkpoint_sha256', 'elapsed_ticks',
|
||||
'absolute_tick', 'delta_sha256', 'carry_sha256'), 'idle checkpoint')
|
||||
for field in ('checkpoint_sha256', 'parent_checkpoint_sha256', 'delta_sha256'):
|
||||
_sha(checkpoint[field], field)
|
||||
require(type(checkpoint['elapsed_ticks']) is int and checkpoint['elapsed_ticks'] == second * 10000 and
|
||||
type(checkpoint['absolute_tick']) is int and checkpoint['absolute_tick'] >= 0,
|
||||
'Retention clock differs')
|
||||
start = checkpoint['absolute_tick'] if second == 0 else start
|
||||
require(checkpoint['absolute_tick'] == start + second * 10000 and checkpoint['delta_sha256'] == branch['delta_sha256'],
|
||||
'Absolute clock or idle delta changed')
|
||||
require(checkpoint['parent_checkpoint_sha256'] == (branch['source_checkpoint_sha256'] if previous is None else previous),
|
||||
'Idle checkpoint chain does not preserve the same 1-to-10-second trajectory')
|
||||
_keys(checkpoint['carry_sha256'], CARRY, 'complete carried-state hashes')
|
||||
for field, value in checkpoint['carry_sha256'].items():
|
||||
_sha(value, field)
|
||||
previous = checkpoint['checkpoint_sha256']
|
||||
|
||||
|
||||
def evaluate_retention(replicates, *, mode, dan_type, conditioned_cue, registry, authority,
|
||||
nodes, populations, downstream_policy):
|
||||
"""One conjunction per training replicate at BOTH 1 and 10 real seconds."""
|
||||
require(downstream_policy == DOWNSTREAM_POLICY, 'Explicit preregistered downstream operationalization required')
|
||||
_context(registry, authority, nodes, populations)
|
||||
_cell_rows(replicates, registry, mode, dan_type, conditioned_cue)
|
||||
reports, idle_used = [], set()
|
||||
used = dict(snapshots={}, receipts={})
|
||||
for row in replicates:
|
||||
_keys(row, ('replicate_id', 'replicate_unit', 'training_stream_ids', 'evaluation_stream_ids',
|
||||
'pre', 'checkpoints', 'execution'), 'retention row')
|
||||
_keys(row['pre'], ('trained', 'frozen'), 'retention pre')
|
||||
_keys(row['execution'], ('trained', 'frozen'), 'retention branches')
|
||||
_keys(row['checkpoints'], ('0', '1', '10'), 'retention time inventory')
|
||||
block_id = row['replicate_id']
|
||||
pre = {}
|
||||
for branch in ('trained', 'frozen'):
|
||||
execution = row['execution'][branch]
|
||||
_idle(execution, idle_used, arm='paired' if branch == 'trained' else 'frozen', conditioned_cue=conditioned_cue)
|
||||
pre[branch] = _pair(row['pre'][branch], block_id, registry, nodes, populations, used, policy='common_frozen_reset',
|
||||
delta=execution['source_execution']['initial_delta_sha256'])
|
||||
times, complete = {}, []
|
||||
for second in (0, 1, 10):
|
||||
pairs = row['checkpoints'][str(second)]
|
||||
_keys(pairs, ('trained', 'frozen'), 'time-matched trained/frozen probes')
|
||||
states, metrics = {}, {}
|
||||
for branch in ('trained', 'frozen'):
|
||||
execution = row['execution'][branch]
|
||||
checkpoint = execution['checkpoints'][str(second)]
|
||||
states[branch] = _pair(pairs[branch], block_id, registry, nodes, populations, used,
|
||||
policy='continuous_checkpoint', delta=execution['delta_sha256'], checkpoint=checkpoint['checkpoint_sha256'])
|
||||
metrics[branch] = M.arm_metrics(pre[branch], states[branch], conditioned_cue=conditioned_cue, nodes=nodes, populations=populations)
|
||||
differences = {cue: M.functional_summary(states['frozen'][cue], states['trained'][cue],
|
||||
nodes=nodes, populations=populations, steps=1200) for cue in M.CUES}
|
||||
trained, frozen = (metrics[branch]['rawS'] for branch in ('trained', 'frozen'))
|
||||
mbon, down = (differences[conditioned_cue]['populations'][name] for name in ('MBON', 'nonMBONDownstream'))
|
||||
predicates = dict(raw_signed_direction=bool(trained > 0 if dan_type == 'PAM15' else trained < 0),
|
||||
beyond_time_matched_frozen=bool(trained > frozen if dan_type == 'PAM15' else trained < frozen),
|
||||
conditioned_MBON_count_or_defined_first_latency=bool(mbon['spike_count_l1'] > 0 or mbon['defined_first_latency_changed']),
|
||||
conditioned_nonMBONDownstream_event_or_count=bool(down['events_changed'] or down['spike_count_l1'] > 0))
|
||||
times[str(second)] = dict(rawS_trained=trained, rawS_frozen=frozen, rawS_trained_minus_frozen=trained - frozen,
|
||||
metrics=metrics, frozen_to_trained_differences_by_cue=differences, predicates=predicates,
|
||||
contributes_to_gate=second in (1, 10), conjunction_pass=all(predicates.values()))
|
||||
if second in (1, 10):
|
||||
complete.append(all(predicates.values()))
|
||||
reports.append(dict(replicate_id=block_id, times=times, conjunction_pass=all(complete),
|
||||
legacy_style_last_MBON_separation_exceeds_pre=bool(times['10']['metrics']['trained']['separation']['MBON']['gain'] > 0),
|
||||
legacy_reset_retention_equivalence_claimed=False))
|
||||
return _report('retention', reports, registry, authority, mode, dan_type, conditioned_cue)
|
||||
|
||||
|
||||
def _checked_difference(summary, before, after, cue):
|
||||
"""Rebind reported differences to raw vectors in their two source metrics.
|
||||
|
||||
The event-change bit comes from raw-event comparison in evaluate_*; a summary
|
||||
does not contain the event files. It remains externally bound evidence, never
|
||||
an independent disk/event verification performed by this cohort function.
|
||||
"""
|
||||
left, right = before['cues'][cue], after['cues'][cue]
|
||||
require(summary['membership'] == left['membership'] == right['membership'] and
|
||||
summary['nodes_raw_sha256'] == left['nodes_raw_sha256'] == right['nodes_raw_sha256'] and
|
||||
summary['pre_state_raw_sha256'] == left['post_state_raw_sha256'] and
|
||||
summary['post_state_raw_sha256'] == right['post_state_raw_sha256'], 'Difference source binding changed')
|
||||
for name in M.POPULATIONS:
|
||||
value, a, b = summary['populations'][name], left['populations'][name], right['populations'][name]
|
||||
for field in ('counts', 'first_latency_ms_per_neuron', 'final_v', 'final_g', 'final_ref'):
|
||||
require(value['pre_' + field] == a['post_' + field] and value['post_' + field] == b['post_' + field],
|
||||
'Difference population vectors changed')
|
||||
count = sum(abs(x - y) for x, y in zip(value['pre_counts'], value['post_counts']))
|
||||
first = []
|
||||
for phase in ('pre', 'post'):
|
||||
defined = [x for x in value[phase + '_first_latency_ms_per_neuron'] if x is not None]
|
||||
first.append(min(defined) if defined else None)
|
||||
changed = first[0] is not None and first[1] is not None and first[0] != first[1]
|
||||
require(type(value['spike_count_l1']) is int and value['spike_count_l1'] == count and
|
||||
value['defined_first_latency_changed'] is changed and type(value['events_changed']) is bool,
|
||||
'Difference predicate contradicts its raw count/defined-latency vectors')
|
||||
require(count == 0 or value['events_changed'], 'Changed counts require changed events')
|
||||
same_events = all(summary['pre_state_raw_sha256'][key] == summary['post_state_raw_sha256'][key]
|
||||
for key in ('step', 'neuron_idx'))
|
||||
require(not same_events or not value['events_changed'], 'Identical complete event arrays cannot change population events')
|
||||
return summary['populations']
|
||||
|
||||
|
||||
def _validate_followup_report(row, assay, dan, cue):
|
||||
neutral = next(x for x in M.CUES if x != cue)
|
||||
if assay == 'reversal':
|
||||
_keys(row['metrics'], ('acquisition', 'reversal', 'no_reversal'), 'reversal report metrics')
|
||||
metrics = {name: M._bound_metric(value, cue) for name, value in row['metrics'].items()}
|
||||
for odor in M.CUES:
|
||||
require(len({tuple(sorted(metric['cues'][odor]['pre_state_raw_sha256'].items())) for metric in metrics.values()}) == 1,
|
||||
'Reversal reports changed original pre baseline')
|
||||
s = {name: value['rawS'] for name, value in metrics.items()}
|
||||
require(row['rawS'] == s, 'Reversal raw signed result differs from source metrics')
|
||||
_keys(row['acquisition_to_reversal_changes_by_cue'], M.CUES, 'reversal cue changes')
|
||||
groups = {odor: _checked_difference(row['acquisition_to_reversal_changes_by_cue'][odor],
|
||||
metrics['acquisition'], metrics['reversal'], odor) for odor in M.CUES}
|
||||
mbon, down = (groups[neutral][name] for name in ('MBON', 'nonMBONDownstream'))
|
||||
signed = (s['acquisition'] > 0 and s['no_reversal'] > 0 and s['reversal'] < 0) if dan == 'PAM15' else (
|
||||
s['acquisition'] < 0 and s['no_reversal'] < 0 and s['reversal'] > 0)
|
||||
predicates = dict(strict_three_signed_relations=bool(signed),
|
||||
former_neutral_MBON_count_or_defined_first_latency=bool(mbon['spike_count_l1'] > 0 or mbon['defined_first_latency_changed']),
|
||||
former_neutral_nonMBONDownstream_event_or_count=bool(down['events_changed'] or down['spike_count_l1'] > 0))
|
||||
require(row['predicates'] == predicates and all(type(x) is bool for x in row['predicates'].values()),
|
||||
'Reversal predicates differ from source metrics')
|
||||
return all(predicates.values())
|
||||
_keys(row['times'], ('0', '1', '10'), 'retention report times')
|
||||
baselines, conjunctions = {}, []
|
||||
for second in ('0', '1', '10'):
|
||||
value = row['times'][second]
|
||||
_keys(value['metrics'], ('trained', 'frozen'), 'retention report metrics')
|
||||
metrics = {name: M._bound_metric(metric, cue) for name, metric in value['metrics'].items()}
|
||||
for branch, metric in metrics.items():
|
||||
baseline = {odor: metric['cues'][odor]['pre_state_raw_sha256'] for odor in M.CUES}
|
||||
require(branch not in baselines or baselines[branch] == baseline, 'Retention changed original pre baseline across time')
|
||||
baselines[branch] = baseline
|
||||
trained, frozen = (metrics[branch]['rawS'] for branch in ('trained', 'frozen'))
|
||||
require(value['rawS_trained'] == trained and value['rawS_frozen'] == frozen and
|
||||
value['rawS_trained_minus_frozen'] == trained - frozen, 'Retention signed contrast differs from source metrics')
|
||||
_keys(value['frozen_to_trained_differences_by_cue'], M.CUES, 'retention cue differences')
|
||||
groups = {odor: _checked_difference(value['frozen_to_trained_differences_by_cue'][odor],
|
||||
metrics['frozen'], metrics['trained'], odor) for odor in M.CUES}
|
||||
mbon, down = (groups[cue][name] for name in ('MBON', 'nonMBONDownstream'))
|
||||
predicates = dict(raw_signed_direction=bool(trained > 0 if dan == 'PAM15' else trained < 0),
|
||||
beyond_time_matched_frozen=bool(trained > frozen if dan == 'PAM15' else trained < frozen),
|
||||
conditioned_MBON_count_or_defined_first_latency=bool(mbon['spike_count_l1'] > 0 or mbon['defined_first_latency_changed']),
|
||||
conditioned_nonMBONDownstream_event_or_count=bool(down['events_changed'] or down['spike_count_l1'] > 0))
|
||||
require(value['predicates'] == predicates and all(type(x) is bool for x in value['predicates'].values()) and
|
||||
value['conjunction_pass'] is all(predicates.values()) and value['contributes_to_gate'] is (second != '0'),
|
||||
'Retention predicates differ from source metrics')
|
||||
if second != '0':
|
||||
conjunctions.append(all(predicates.values()))
|
||||
return all(conjunctions)
|
||||
|
||||
|
||||
def summarize_cohort(reports, *, registry, authority, required_assays):
|
||||
"""Exact eight-cell inventory; each assay keeps its own same-replicate 3/5.
|
||||
|
||||
Use ('normal',) for the staged acquisition decision or ASSAYS for the full
|
||||
functional table. The function does not silently intersect successful seeds
|
||||
across assays, pool cells, or incorporate legacy H/integrity gates. Those are
|
||||
separately registered coordinator decisions. Missing assays remain NOT-RUN.
|
||||
"""
|
||||
_context(registry, authority)
|
||||
require(tuple(required_assays) in (('normal',), ASSAYS), 'Only staged normal or full fixed assay scope supported')
|
||||
expected = {(m, d, c, a) for m in M.MODES for d in M.DAN_TYPES for c in M.CUES for a in required_assays}
|
||||
actual, table = set(), []
|
||||
for report in reports:
|
||||
require(report.get('schema') == SCHEMA and report.get('registry_sha256') == authority['registry_sha256'] and
|
||||
report.get('external_data_authority_descriptor_sha256') == descriptor_sha256(authority), 'Report authority binding differs')
|
||||
identity = (report['mode'], report['dan_type'], report['conditioned_cue'], report['assay'])
|
||||
require(identity in expected and identity not in actual, 'Duplicate/unexpected cohort cell/assay')
|
||||
expected_ids = {key for key, value in registry['blocks'].items()
|
||||
if (value['mode'], value['dan_type'], value['conditioned_cue']) == identity[:3]}
|
||||
rows = report['replicates']
|
||||
require(len(rows) == 5 and {row['replicate_id'] for row in rows} == expected_ids and
|
||||
all(type(row['conjunction_pass']) is bool for row in rows), 'Cohort replicate coverage differs')
|
||||
if report['assay'] in ('normal', 'delayed'):
|
||||
inputs = report.get('acquisition_metric_inputs')
|
||||
require(isinstance(inputs, list), 'Missing original normal/delayed metric inputs')
|
||||
rebuilt = evaluate_acquisition(inputs, assay=identity[3], mode=identity[0], dan_type=identity[1],
|
||||
conditioned_cue=identity[2], registry=registry, authority=authority)
|
||||
require(rebuilt == report,
|
||||
'Normal/delayed report differs from frozen gate reconstruction')
|
||||
else:
|
||||
for row in rows:
|
||||
require(report['downstream_policy'] == DOWNSTREAM_POLICY, 'Follow-up downstream policy changed')
|
||||
conjunction = _validate_followup_report(row, report['assay'], report['dan_type'], report['conditioned_cue'])
|
||||
require(row['conjunction_pass'] is conjunction, 'Replicate conjunction differs from its predicates')
|
||||
count = sum(row['conjunction_pass'] for row in rows)
|
||||
require(report['successful_same_replicate_conjunctions'] == count and report['predicate_pass'] is (count >= 3),
|
||||
'Cohort summary disagrees with replicate conjunctions')
|
||||
require(all(report.get(key) is False for key in ('external_authority_verified', 'scientific_learning_pass_claimed',
|
||||
'candidate_generated', 'execution_authorized', 'data_backed_claimed')), 'Conditional report contains an unsupported authority claim')
|
||||
actual.add(identity)
|
||||
table.append(dict(mode=identity[0], dan_type=identity[1], conditioned_cue=identity[2], assay=identity[3],
|
||||
status='CONDITIONAL-PASS' if count >= 3 else 'CONDITIONAL-FAIL', successful_replicates=count))
|
||||
for identity in sorted(expected - actual):
|
||||
table.append(dict(mode=identity[0], dan_type=identity[1], conditioned_cue=identity[2], assay=identity[3], status='NOT-RUN', successful_replicates=None))
|
||||
complete = actual == expected
|
||||
return dict(schema=SCHEMA, status='COMPLETE' if complete else 'NOT-RUN', required_assays=list(required_assays),
|
||||
complete_inventory=complete, all_functional_predicates_pass=(all(row['status'] == 'CONDITIONAL-PASS' for row in table) if complete else None),
|
||||
table=sorted(table, key=lambda row: (row['mode'], row['dan_type'], row['conditioned_cue'], row['assay'])),
|
||||
legacy_H_and_integrity_gates_included=False, **_scope())
|
||||
|
||||
|
||||
def legacy_h_cohort_audit(normal_reports, *, registry, authority, declared_mapping):
|
||||
"""Four groups, two frozen H calls each; no branch/control pooling.
|
||||
|
||||
Both stricter control-source mapping and both_pass aggregate are new explicit
|
||||
pre-outcome operationalizations, NOT a reproduced complete original H gate.
|
||||
"""
|
||||
if declared_mapping is None:
|
||||
return dict(schema=SCHEMA, status='NOT-TESTABLE', both_pass=None,
|
||||
reason='Missing explicit pre-outcome control-source mapping', **_scope())
|
||||
require(declared_mapping == H_MAPPING, 'Unknown declared H control-source mapping')
|
||||
inventory = summarize_cohort(normal_reports, registry=registry, authority=authority, required_assays=('normal',))
|
||||
if not inventory['complete_inventory']:
|
||||
return dict(schema=SCHEMA, status='NOT-RUN', both_pass=None, reason='Complete eight normal cells required', **_scope())
|
||||
lookup = {(r['mode'], r['dan_type'], r['conditioned_cue']): r for r in normal_reports}
|
||||
groups = []
|
||||
for mode in M.MODES:
|
||||
for cue in M.CUES:
|
||||
reports = {dan: lookup[(mode, dan, cue)] for dan in M.DAN_TYPES}
|
||||
outcomes = {}
|
||||
for source in M.DAN_TYPES:
|
||||
# The normal report must retain all raw arm metrics; gains are
|
||||
# taken from their validated source payload, not a selected mean.
|
||||
gains = {}
|
||||
for dan, label in (('PAM15', 'appetitive-conditioning'), ('PPL103', 'aversive-conditioning')):
|
||||
gains[label] = [row['population_separation_gains']['MBON'] for row in reports[dan]['replicates']]
|
||||
controls = reports[source].get('legacy_control_MBON_gains')
|
||||
require(isinstance(controls, Mapping) and set(controls) == {'D=0', 'random reward', 'frozen'},
|
||||
'Normal report lacks complete branch-bound legacy control gains')
|
||||
for name, label in (('D=0', 'd-zero-control'), ('random reward', 'random-reward-control'), ('frozen', 'frozen-brain-control')):
|
||||
require(set(controls[name]) == {row['replicate_id'] for row in reports[source]['replicates']}, 'Legacy control replicate mapping differs')
|
||||
gains[label] = [controls[name][row['replicate_id']] for row in reports[source]['replicates']]
|
||||
outcomes[source] = M.legacy_h_mean_control_audit(gains)
|
||||
groups.append(dict(mode=mode, conditioned_cue=cue, control_sources=outcomes,
|
||||
both_pass=all(value['predicate_pass'] for value in outcomes.values())))
|
||||
return dict(schema=SCHEMA, status='CONDITIONAL-AUDIT', declared_mapping=declared_mapping, groups=groups,
|
||||
both_pass=all(group['both_pass'] for group in groups), original_H_data_layout_reproduced=False,
|
||||
new_stricter_control_source_mapping=True, **_scope())
|
||||
@@ -0,0 +1,178 @@
|
||||
"""Exclusive preregistration for a finite NEW execution-boundary experiment.
|
||||
|
||||
No sampler, brain, update or historical experiment is executed by preparation.
|
||||
Frozen checksums are read. Future outputs are derived later from explicit rules,
|
||||
never given fabricated preregistered hashes. Real learning is NOT authorized.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import importlib.util
|
||||
import json
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
import numpy as np
|
||||
|
||||
import boundary_plan as PLAN
|
||||
import execution_authority as A
|
||||
|
||||
ROOT=Path('/data/digital-drosophila')
|
||||
MODEL=Path(__file__).resolve().parent
|
||||
EXP=ROOT/'experiments/phase4aq-conditioning-execution'
|
||||
AP=ROOT/'experiments/phase4ap-conditioning-interface-v2'
|
||||
AO=ROOT/'experiments/phase4ao-conditioning-interface'
|
||||
LAB=MODEL.parent/'olfactory-conditioning-lab-v1'
|
||||
require,read,digest=A.require,A.read,A.digest
|
||||
|
||||
|
||||
def save(path,value):
|
||||
with Path(path).open('x',encoding='utf-8') as f:
|
||||
json.dump(value,f,sort_keys=True,indent=2,allow_nan=False,ensure_ascii=False);f.write('\n')
|
||||
|
||||
|
||||
def copy_exclusive(source,target):
|
||||
with Path(source).open('rb') as inp,Path(target).open('xb') as out:shutil.copyfileobj(inp,out)
|
||||
require(digest(source)==digest(target),'Exclusive source copy differs')
|
||||
|
||||
|
||||
def npz(path):
|
||||
with np.load(path,allow_pickle=False) as f:return {n:f[n].copy() for n in f.files}
|
||||
|
||||
|
||||
def save_npz(path,values):
|
||||
with Path(path).open('xb') as f:np.savez_compressed(f,**values)
|
||||
|
||||
|
||||
def verify(pins):
|
||||
for path,sha in pins.items():require(A.pin(path)['sha256']==sha,'Pinned input changed: '+str(path))
|
||||
|
||||
|
||||
def old_context():
|
||||
pins={str(AP/k):v for k,v in PLAN.AP_ANCHORS.items()}
|
||||
pins.update({str(MODEL.parent/k):v for k,v in PLAN.SOURCE_PINS.items()})
|
||||
verify(pins)
|
||||
apreg=read(AP/'protocol/preregistered.json')
|
||||
verify({**apreg['input_sha256'],**apreg['source_sha256'],**apreg['prepared_file_sha256']})
|
||||
path=MODEL.parent/'conditioning-interface-v2/coordinator.py'
|
||||
raw=path.read_bytes();name='_conditioning_execution_prior_integrity'
|
||||
require(name not in sys.modules,'Fresh preparation/integrity process required')
|
||||
spec=importlib.util.spec_from_file_location(name,path);module=importlib.util.module_from_spec(spec)
|
||||
sys.modules[name]=module;exec(compile(raw,str(path),'exec'),module.__dict__)
|
||||
return module,apreg,pins
|
||||
|
||||
|
||||
def integrity():
|
||||
old,apreg,pins=old_context()
|
||||
earlier=old.previous_integrity();current=old.helper().verify_seal(AP)
|
||||
require(read(AP/'audit/final-status.json')['status']=='PASS-EXACT-PROCESS-ISOLATED-DELTA-INTERFACE-NOT-LEARNING',
|
||||
'AP interface gate changed')
|
||||
return dict(complete=True,AP=current,prior=earlier,anchors=pins,
|
||||
old_experiments_reexecuted=False,old_files_modified=False,
|
||||
five_frozen_reference_trials_rerun_here=False,
|
||||
historical_reference_evidence_scope='Preserved AM numerical regression evidence; checksums now reverified',
|
||||
scientific_learning_pass_claimed=False)
|
||||
|
||||
|
||||
def source_inventory():
|
||||
entries=list(MODEL.iterdir())
|
||||
require(entries and all(p.is_file() and not p.is_symlink() and p.suffix in ('.py','.md') for p in entries),
|
||||
'Source directory may contain only explicit unlinked Python/Markdown source files')
|
||||
return {str(p):digest(p) for p in sorted(entries)}
|
||||
|
||||
|
||||
def prepare():
|
||||
require(sys.dont_write_bytecode and EXP.is_dir() and not any(EXP.iterdir()),'Use -B and exact new empty experiment directory')
|
||||
old,apreg,anchors=old_context()
|
||||
before=dict(complete=True,AP=old.helper().verify_seal(AP),prior=old.previous_integrity(),
|
||||
five_frozen_reference_trials_rerun_here=False,old_files_modified=False)
|
||||
plan=PLAN.build_plan();PLAN.validate_plan(plan)
|
||||
source=source_inventory();commit=subprocess.check_output(['git','-C',str(ROOT),'rev-parse','HEAD']).decode().strip()
|
||||
require(len(commit)==40,'Missing actual code commit')
|
||||
for path,sha in source.items():
|
||||
raw=subprocess.check_output(['git','-C',str(ROOT),'show',commit+':'+Path(path).relative_to(ROOT).as_posix()])
|
||||
require(hashlib.sha256(raw).hexdigest()==sha,'Source not equal to committed blob: '+path)
|
||||
budget=dict(root=str(EXP),output_cap_bytes=4*1024**3,minimum_free_reserve_bytes=10*1024**3,
|
||||
child_timeout_seconds=1800,workflow_timeout_seconds=7200)
|
||||
require(shutil.disk_usage(EXP).free>=budget['output_cap_bytes']+budget['minimum_free_reserve_bytes'],
|
||||
'Insufficient space for finite validation budget')
|
||||
pins={**anchors,**apreg['input_sha256'],**apreg['source_sha256'],**apreg['prepared_file_sha256']}
|
||||
parents={}
|
||||
for arm,descriptor in plan['imported_parents'].items():
|
||||
directory=Path(descriptor['checkpoint_manifest']).parent
|
||||
record=old.C.load_checkpoint(directory,descriptor['sha256'])
|
||||
require(record['fresh'] and record['steps']==1200,'Imported parent is not the declared fresh epoch')
|
||||
authority=AP/'jobs'/f'{arm}--reference--epoch-001.authority.json'
|
||||
update=AP/'updates'/f'{arm}--reference--epoch-001'
|
||||
ea=read(authority)
|
||||
require(ea['checkpoint_dir']==str(directory) and ea['checkpoint_manifest_sha256']==descriptor['sha256'],
|
||||
'Original update authority is not bound to selected parent')
|
||||
for path in (directory/'checkpoint-manifest.json',authority,*update.iterdir()):pins[str(path)]=digest(path)
|
||||
parents[descriptor['role']]=dict(directory=str(directory),checkpoint_sha256=descriptor['sha256'],
|
||||
epoch_authority=A.pin(authority),update_dir=str(update),update_sha256={p.name:digest(p) for p in update.iterdir()},
|
||||
before_overlay=dict(overlay_file=ea['files']['overlay_before']['path'],overlay_manifest=ea['files']['overlay_manifest_before']['path']),
|
||||
after_overlay=dict(overlay_file=str(update/'delta-after.npz'),overlay_manifest=str(update/'overlay-manifest.json')))
|
||||
zero=apreg['initial_overlay']
|
||||
require(A.pin(zero['overlay_file'])==plan['initial_overlay']['overlay_file'] and
|
||||
A.pin(zero['overlay_manifest'])==plan['initial_overlay']['overlay_manifest'],'Initial zero reference differs')
|
||||
require(not np.any(npz(zero['overlay_file'])['plastic_delta_mv'].view(np.uint32)),'Initial delta is not positive zero')
|
||||
template=read(AP/'cases/D1--reference--epoch-001/spec.json')
|
||||
for name in ('protocol/source-snapshot','protocol/case-templates','inputs/static','cases','runs','updates',
|
||||
'jobs','authorities','receipts','logs','audit','regression'):(EXP/name).mkdir(parents=True)
|
||||
for path in source:copy_exclusive(path,EXP/'protocol/source-snapshot'/Path(path).name)
|
||||
save(EXP/'regression/integrity-before.json',before)
|
||||
templates={}
|
||||
for call in plan['calls']:
|
||||
group=call.get('case_group',call['call_id'])
|
||||
spec=PLAN.derive_case_spec(template,call['call_id'],budget_root=str(EXP))
|
||||
if group in templates:require(spec==read(templates[group]),'Shared comparison case templates differ')
|
||||
else:
|
||||
dest=EXP/'protocol/case-templates'/f'{group}.json';save(dest,spec);templates[group]=str(dest)
|
||||
ea=read(parents[plan['imported_parents']['D1']['role']]['epoch_authority']['path'])
|
||||
candidate=npz(ea['files']['candidate_map']['path'])
|
||||
population_file=AO/'inputs/static/populations.npz'
|
||||
require(str(population_file) in pins,'Original anatomical population inventory not pinned by AP')
|
||||
populations=npz(population_file);dan=populations['PAM15']
|
||||
requests,selection=PLAN.mechanical_requests(candidate,dan,identity_binding=dict(
|
||||
candidate_map_sha256=ea['files']['candidate_map']['sha256'],
|
||||
pam15_membership_sha256=hashlib.sha256(dan.tobytes()).hexdigest()))
|
||||
require(np.isin(candidate['source_neuron_idx'],populations['Kenyon_Cell']).all(),'Candidate source outside original KC population')
|
||||
save_npz(EXP/'inputs/static/mechanical-requests.npz',requests)
|
||||
save(EXP/'inputs/static/mechanical-selection.json',selection)
|
||||
# Original physiological PN mapping is recomputed without stochastic sampling.
|
||||
import conditioning_preflight_inputs as I
|
||||
rates=I.load_rate_tables(ROOT)
|
||||
for cue,table in rates['tables'].items():
|
||||
existing=npz(AO/f'inputs/static/{cue}-rates.npz')
|
||||
require(all(table[k].dtype==existing[k].dtype and table[k].shape==existing[k].shape and
|
||||
table[k].tobytes()==existing[k].tobytes() for k in ('targets','rates_hz')),
|
||||
'Prior physiological PN mapping differs')
|
||||
copy_exclusive(AO/f'inputs/static/{cue}-rates.npz',EXP/f'inputs/static/{cue}-rates.npz')
|
||||
save(EXP/'inputs/static/rate-audit.json',rates['audit'])
|
||||
fullplan=AO/'protocol/full-trial-plan.json'
|
||||
require(str(fullplan) in pins,'Original full seed/trial plan not pinned')
|
||||
prepared={str(p):digest(p) for sub in ('protocol','inputs/static','regression') for p in (EXP/sub).rglob('*') if p.is_file()}
|
||||
reg=dict(schema='conditioning-execution-registration-v1',engineering_only=True,scientific_acquisition_authorized=False,
|
||||
scope='bounded updated-state boundary, fixed functional-gate code, complete-process budget measurement',
|
||||
plan=plan,source_sha256=source,source_code_commit=commit,input_sha256=pins,prepared_file_sha256=prepared,
|
||||
parent_records=parents,initial_overlay=zero,case_templates=templates,budget=budget,original_full_plan=A.pin(fullplan),
|
||||
old_source_changes=False,old_experiments_reexecuted=False,brain_or_sampler_run_during_preparation=False,
|
||||
future_hashes_fabricated=False,learning_success_claimed=False,
|
||||
failure_policy='stop and preserve partials; never automatic retry, tuning, seed search, or trial truncation')
|
||||
verify({**pins,**source,**prepared})
|
||||
save(EXP/'protocol/preregistered.json',reg)
|
||||
return digest(EXP/'protocol/preregistered.json')
|
||||
|
||||
|
||||
if __name__=='__main__':
|
||||
parser=argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('mode',choices=('prepare','integrity'))
|
||||
parser.add_argument('--output')
|
||||
args=parser.parse_args()
|
||||
if args.mode=='prepare':print('REGISTRATION_SHA256',prepare(),flush=True)
|
||||
else:
|
||||
require(args.output and not Path(args.output).exists(),'Exclusive integrity report required')
|
||||
save(args.output,integrity());print('INTEGRITY_SHA256',digest(args.output),flush=True)
|
||||
@@ -0,0 +1,299 @@
|
||||
"""Synthetic file-chain/dispatch tests; never a brain or historical audit."""
|
||||
from __future__ import annotations
|
||||
|
||||
import copy
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
import tempfile
|
||||
from contextlib import ExitStack
|
||||
from types import SimpleNamespace
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
import numpy as np
|
||||
|
||||
import audit_execution as T
|
||||
|
||||
|
||||
def write(path, value):
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
path.write_text(json.dumps(value, sort_keys=True), encoding='utf-8')
|
||||
|
||||
|
||||
def npz(path, **values):
|
||||
with path.open('wb') as stream:
|
||||
np.savez(stream, **values)
|
||||
|
||||
|
||||
class PlanTests(unittest.TestCase):
|
||||
def test_exact_fixed_process_budget_and_kinds(self):
|
||||
plan = T.PLAN.build_plan(); values = T.expected_processes(plan)
|
||||
self.assertEqual(len(values), 31)
|
||||
self.assertEqual(sum(k in ('updated', 'oracle', 'unchanged', 'brain') for k in values.values()), 23)
|
||||
self.assertEqual(sum(k in ('update', 'validate_cpu') for k in values.values()), 7)
|
||||
self.assertEqual(list(values.values()).count('sample'), 1)
|
||||
self.assertEqual(sum(c['steps'] for c in plan['calls']), 125200)
|
||||
|
||||
def test_duplicate_call_and_wrong_budget_rejected(self):
|
||||
plan = T.PLAN.build_plan(); plan['calls'].append(copy.deepcopy(plan['calls'][0]))
|
||||
with self.assertRaisesRegex(ValueError, 'Duplicate'): T.expected_processes(plan)
|
||||
plan = T.PLAN.build_plan(); plan['counts']['total_children'] += 1
|
||||
with self.assertRaisesRegex(ValueError, 'inventory'): T.expected_processes(plan)
|
||||
|
||||
def test_D1_zero_coverage_does_not_deny_mechanical_witness(self):
|
||||
pending = {'D1': {'accepted_changed_edge_witness_verified': False},
|
||||
'mechanical': {'accepted_changed_edge_witness_verified': True}}
|
||||
exact, coverage, status = T.outcome({'all_numeric': True}, pending)
|
||||
self.assertTrue(exact and coverage)
|
||||
self.assertEqual(status, 'PASS-EXACT-UPDATED-BOUNDARY-ENGINEERING-NOT-LEARNING')
|
||||
pending['mechanical']['accepted_changed_edge_witness_verified'] = False
|
||||
self.assertEqual(T.outcome({'all_numeric': True}, pending)[2], 'INCOMPLETE-CHANGED-EDGE-COVERAGE')
|
||||
self.assertEqual(T.outcome({'all_numeric': False}, pending)[2], 'FAIL-NUMERICAL-OR-LINEAGE')
|
||||
with self.assertRaises(ValueError): T.outcome({}, pending)
|
||||
with self.assertRaises(ValueError): T.outcome({'impostor_bool': 1}, pending)
|
||||
|
||||
|
||||
class ProcessTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.temp = tempfile.TemporaryDirectory(); self.exp = Path(self.temp.name).resolve() / 'phase4aq-synthetic'
|
||||
self.patch = patch.object(T, 'EXP', self.exp); self.patch.start()
|
||||
self.name = 'performance--natural-light-fresh'; self.kind = 'brain'
|
||||
self.regfile = self.exp / 'protocol/preregistered.json'; write(self.regfile, {'synthetic': True})
|
||||
self.reg_sha = T.digest(self.regfile)
|
||||
self.h = T._helpers()
|
||||
self.reg = dict(source_sha256={str(T.MODEL / 'isolated_execution.py'): T.digest(T.MODEL / 'isolated_execution.py')},
|
||||
input_sha256={}, prepared_file_sha256={})
|
||||
case = self.exp / 'cases' / self.name; write(case / 'spec.json', {'synthetic': True})
|
||||
(case / 'requests.npz').write_bytes(b'not-scientific-requests')
|
||||
overlay = self.exp / 'inputs/before.npz'; overlay.parent.mkdir(); overlay.write_bytes(b'not-scientific-overlay')
|
||||
om = self.exp / 'inputs/before.json'; write(om, {})
|
||||
self.output = self.exp / 'runs' / self.name; write(self.output / 'summary.json', {'synthetic': True})
|
||||
self.jobpath = self.exp / 'jobs' / (self.name + '.json')
|
||||
self.workerpath = self.exp / 'receipts' / (self.name + '.worker.json')
|
||||
self.processpath = self.exp / 'receipts' / (self.name + '.process.json')
|
||||
self.stdout = self.exp / 'logs' / (self.name + '.stdout.log'); self.stdout.parent.mkdir()
|
||||
self.stdout.write_bytes(b'fixture'); self.stderr = self.stdout.with_name(self.name + '.stderr.log'); self.stderr.write_bytes(b'')
|
||||
self.sources = {n: dict(path=str(T.LAB / (n + '.py')), sha256=self.h.SOURCE_PINS[n])
|
||||
for n in ('runtime_light', 'runtime_continuation')}
|
||||
inputs = T._closure(self.reg, self.reg_sha)
|
||||
inputs.update({str(p): T.digest(p) for p in (case / 'spec.json', case / 'requests.npz', overlay, om)})
|
||||
self.job = dict(schema='phase4ap-isolated-worker-job-v1', job_id=self.name, kind='brain', registration_sha256=self.reg_sha,
|
||||
worker_sha256=T.W.AP_SHA, case_dir=str(case), overlay_file=str(overlay), overlay_manifest=str(om),
|
||||
output_dir=str(self.output), receipt_file=str(self.workerpath), input_sha256=inputs, sources=self.sources)
|
||||
self.seal_records()
|
||||
|
||||
def tearDown(self):
|
||||
self.patch.stop(); self.temp.cleanup()
|
||||
|
||||
def seal_records(self):
|
||||
write(self.jobpath, self.job); job_sha = T.digest(self.jobpath)
|
||||
attempt = Path(str(self.workerpath) + '.attempt.json')
|
||||
write(attempt, dict(complete=False, job_sha256=job_sha, no_automatic_retry=True))
|
||||
hashes = {k: v['sha256'] for k, v in T.tree(self.output).items()}
|
||||
pins = {**self.job['input_sha256'], str(self.jobpath): job_sha, str(T.W.AP): T.W.AP_SHA,
|
||||
**{v['path']: v['sha256'] for v in self.sources.values()}}
|
||||
receipt = dict(schema='phase4ap-isolated-worker-receipt-v1', complete=True, job_id=self.name, kind='brain',
|
||||
registration_sha256=self.reg_sha, worker_sha256=T.W.AP_SHA, job_sha256=job_sha,
|
||||
process_exit_independently_observed=False, scientific_gate_pass_claimed=False, source_files=self.sources,
|
||||
verified_input_sha256=pins, output_dir=str(self.output), output_files_sha256=hashes,
|
||||
attempt_sha256=T.digest(attempt), result={'synthetic': True})
|
||||
write(self.workerpath, receipt)
|
||||
process = dict(schema='conditioning-execution-process-v1', name=self.name, kind='brain', registration_sha256=self.reg_sha,
|
||||
complete=True, exit_code=0, timed_out=False, job_sha256=job_sha, worker_receipt_sha256=T.digest(self.workerpath),
|
||||
stdout_sha256=T.digest(self.stdout), stderr_sha256=T.digest(self.stderr),
|
||||
argv=['/synthetic/python', '-B', str(T.W.AP), 'brain', '--job', str(self.jobpath), '--job-sha256', job_sha],
|
||||
output_bytes=sum(v['bytes'] for v in T.tree(self.output).values()),
|
||||
output_inventory_sha256=hashlib.sha256(json.dumps(hashes, sort_keys=True).encode()).hexdigest(),
|
||||
child_wall_seconds=.1, end_to_end_seconds=.2, validation_wall_seconds=.1)
|
||||
write(self.processpath, process)
|
||||
|
||||
def verify(self):
|
||||
return T.verify_process(self.name, self.kind, self.reg, self.reg_sha, self.processpath, self.h)
|
||||
|
||||
def test_actual_file_chain_not_working_memory_flags(self):
|
||||
result = self.verify()
|
||||
self.assertEqual(result['kind'], 'brain'); self.assertEqual(result['output'], self.output)
|
||||
|
||||
def test_nonzero_exit_and_bool_exit_rejected(self):
|
||||
original = T.read(self.processpath)
|
||||
for value in (1, False, None):
|
||||
changed = copy.deepcopy(original); changed['exit_code'] = value; write(self.processpath, changed)
|
||||
with self.subTest(value=value), self.assertRaisesRegex(ValueError, 'recorded process exit'): self.verify()
|
||||
|
||||
def test_log_mutation_and_unknown_output_rejected(self):
|
||||
self.stderr.write_bytes(b'changed')
|
||||
with self.assertRaisesRegex(ValueError, 'file chain'): self.verify()
|
||||
self.stderr.write_bytes(b''); (self.output / 'unreported.json').write_text('{}')
|
||||
with self.assertRaisesRegex(ValueError, 'inventory'): self.verify()
|
||||
|
||||
def test_missing_registration_source_closure_even_rehashed_rejected(self):
|
||||
del self.job['input_sha256'][str(T.MODEL / 'isolated_execution.py')]; self.seal_records()
|
||||
with self.assertRaisesRegex(ValueError, 'closure omitted'): self.verify()
|
||||
|
||||
def test_extra_self_authorized_input_even_rehashed_rejected(self):
|
||||
extra = self.exp / 'arbitrary.txt'; extra.write_text('extra')
|
||||
self.job['input_sha256'][str(extra)] = T.digest(extra); self.seal_records()
|
||||
with self.assertRaisesRegex(ValueError, 'undeclared input'): self.verify()
|
||||
|
||||
def test_wrong_command_and_process_path_rejected(self):
|
||||
p = T.read(self.processpath); p['argv'][2] = '/unregistered/worker.py'; write(self.processpath, p)
|
||||
with self.assertRaisesRegex(ValueError, 'command differs'): self.verify()
|
||||
with self.assertRaisesRegex(ValueError, 'fixed process record'):
|
||||
T.verify_process(self.name, self.kind, self.reg, self.reg_sha, self.stdout, self.h)
|
||||
|
||||
def test_changed_source_snapshot_and_attempt_rejected(self):
|
||||
worker = T.read(self.workerpath); worker['attempt_sha256'] = '0' * 64; write(self.workerpath, worker)
|
||||
p = T.read(self.processpath); p['worker_receipt_sha256'] = T.digest(self.workerpath); write(self.processpath, p)
|
||||
with self.assertRaisesRegex(ValueError, 'Attempt record changed'): self.verify()
|
||||
|
||||
|
||||
class ComparisonTests(unittest.TestCase):
|
||||
def test_light_missing_perstep_is_reported_not_fabricated(self):
|
||||
state = {k: np.zeros(3, np.int32) for k in T.B.C.STATE_KEYS}
|
||||
terminal = {k: np.zeros(3, np.int32) for k in ('spike_ring', 'apl_state', 'apl_pending', 'next_tick')}
|
||||
left = dict(steps=1, global_tick_offset=0, state=state, terminal=terminal, requests=np.empty((0, 5), np.int64),
|
||||
summary={'effective_weights_raw_sha256': '1'*64}, traces={}, state_hashes=None, queues=None)
|
||||
right = copy.deepcopy(left)
|
||||
with patch.object(T.B, '_complete'):
|
||||
report = T._pair(left, right)
|
||||
self.assertTrue(report['numerical_exact']); self.assertFalse(any(report['observed'].values()))
|
||||
right['state']['v'][0] = 1
|
||||
report = T._pair(left, right)
|
||||
self.assertFalse(report['numerical_exact'])
|
||||
self.assertIn('pair.state.v', report['failed_checks'])
|
||||
|
||||
def test_imported_parent_fields_cannot_be_rebound(self):
|
||||
reg = {'parent_records': {'p': {'directory': '/original', 'checkpoint_sha256': '1'*64}}}
|
||||
complete = {'parents': {'p': {**reg['parent_records']['p'], 'cpu_validation': '/new/check.json'}}}
|
||||
self.assertEqual(T._parent(reg, complete, 'p')['directory'], '/original')
|
||||
complete['parents']['p']['directory'] = '/other'
|
||||
with self.assertRaisesRegex(ValueError, 'Imported parent'): T._parent(reg, complete, 'p')
|
||||
|
||||
def test_output_tree_nonfiles_and_pins_are_actual_bytes(self):
|
||||
with tempfile.TemporaryDirectory() as name:
|
||||
p = Path(name).resolve() / 'payload'; p.write_bytes(b'abc')
|
||||
T.verify_pins({str(p): T.digest(p)})
|
||||
with self.assertRaisesRegex(ValueError, 'Pinned file changed'): T.verify_pins({str(p): '0'*64})
|
||||
|
||||
|
||||
class OrchestrationTests(unittest.TestCase):
|
||||
"""Dispatch fixture: deliberately mocked physics/loaders, no scientific PASS."""
|
||||
def fixture(self, exp):
|
||||
plan = T.PLAN.build_plan(); parents = {}; imports = {}; records = {}; verified = {}; templates = {}
|
||||
delta = dict(edge_id=np.array([0], np.int64), plastic_delta_mv=np.array([0], np.float32))
|
||||
def parent(directory, name):
|
||||
directory.mkdir(parents=True, exist_ok=True)
|
||||
write(directory / 'summary.json', {'synthetic': True})
|
||||
write(directory / 'checkpoint-manifest.json', {'synthetic': True})
|
||||
update = exp / 'updates' / name; update.mkdir(parents=True, exist_ok=True)
|
||||
npz(update / 'delta-after.npz', **delta); write(update / 'update-receipt.json', {'same': 'synthetic-U'})
|
||||
write(update / 'overlay-manifest.json', {'synthetic': True})
|
||||
auth = exp / 'authorities' / (name + '.epoch.json'); write(auth, {'synthetic': True})
|
||||
return dict(directory=str(directory), checkpoint_sha256=T.digest(directory / 'checkpoint-manifest.json'),
|
||||
epoch_authority=T.A.pin(auth), update_dir=str(update),
|
||||
after_overlay=dict(overlay_file=str(update / 'delta-after.npz'), overlay_manifest=str(update / 'overlay-manifest.json')))
|
||||
for arm, desc in plan['imported_parents'].items():
|
||||
p = parent(exp / 'old-AP' / arm, 'old-' + arm)
|
||||
desc['checkpoint_manifest'] = str(Path(p['directory']) / 'checkpoint-manifest.json')
|
||||
desc['sha256'] = p['checkpoint_sha256']; parents[desc['role']] = p; imports[arm] = p
|
||||
registered_parents = copy.deepcopy(parents)
|
||||
for call in plan['calls']:
|
||||
name = call['call_id']; out = exp / 'runs' / name
|
||||
if call['runner'] != 'boundary_oracle':
|
||||
p = parent(out, name); parents[name] = p
|
||||
else:
|
||||
out.mkdir(parents=True); write(out / 'summary.json', {'synthetic': True})
|
||||
write(out / 'oracle-manifest.json', dict(schema='conditioning-live-oracle-files-v1', complete=True,
|
||||
files_sha256={'summary.json': T.digest(out / 'summary.json')}))
|
||||
group = call['case_group']; template = exp / 'protocol/case-templates' / (group + '.json')
|
||||
spec = {'synthetic': group, 'steps': call['steps']}
|
||||
if group not in templates: write(template, spec); templates[group] = str(template)
|
||||
if call['parent'] is not None:
|
||||
spec.update(parent_checkpoint_manifest_sha256=parents[call['parent']]['checkpoint_sha256'],
|
||||
global_tick_offset=call['global_tick_offset'])
|
||||
case = exp / 'cases' / group; write(case / 'spec.json', spec)
|
||||
npz(case / 'requests.npz', tick=np.empty(0, np.int32), neuron_idx=np.empty(0, np.int32))
|
||||
record = dict(source=str(out), steps=call['steps'], global_tick_offset=call['global_tick_offset'],
|
||||
summary=dict(nodes=1, edges=1, diagnostic_mode=call['diagnostic_mode'], apl_component={'environment': {}}),
|
||||
state={'v': np.array([0.], np.float64)})
|
||||
if call['runner'] != 'boundary_oracle': record['manifest_sha256'] = parents[name]['checkpoint_sha256']
|
||||
records[str(out)] = record
|
||||
cycle = dict(complete=True, call=call, source_registration_sha256='placeholder', output_inventory={})
|
||||
write(exp / 'receipts' / (name + '.cycle.json'), cycle)
|
||||
for arm, p in imports.items():
|
||||
records[p['directory']] = dict(source=p['directory'], summary={}, manifest_sha256=p['checkpoint_sha256'])
|
||||
reg = dict(schema='conditioning-execution-registration-v1', engineering_only=True, scientific_acquisition_authorized=False,
|
||||
plan=plan, source_sha256={}, input_sha256={}, prepared_file_sha256={}, parent_records=registered_parents,
|
||||
case_templates=templates)
|
||||
regfile = exp / 'protocol/preregistered.json'; write(regfile, reg); sha = T.digest(regfile)
|
||||
kinds = T.expected_processes(plan)
|
||||
for name, kind in kinds.items():
|
||||
out = exp / ('updates' if kind == 'update' else 'runs') / name.removesuffix('--original-E')
|
||||
out.mkdir(parents=True, exist_ok=True)
|
||||
if not any(out.iterdir()): write(out / 'payload.json', {'synthetic': True})
|
||||
job = {'kind': kind}
|
||||
call = next((c for c in plan['calls'] if c['call_id'] == name), None)
|
||||
if call is not None:
|
||||
case = exp / 'cases' / call['case_group']
|
||||
if kind in ('brain', 'unchanged'): job['case_dir'] = str(case)
|
||||
elif kind == 'oracle': job['oracle_case'] = str(case)
|
||||
else:
|
||||
p = parents[call['parent']]
|
||||
auth = dict(case=dict(spec=T.A.pin(case / 'spec.json'), requests=T.A.pin(case / 'requests.npz')),
|
||||
boundary_id=name, registration_sha256=sha, diagnostic_mode=call['diagnostic_mode'],
|
||||
input_policy=call['input_policy'], transition=call['transition'],
|
||||
parent=dict(directory=p['directory'], checkpoint_manifest_sha256=p['checkpoint_sha256']),
|
||||
expected_effective_weight_before_sha256='a'*64, expected_effective_weight_after_sha256='b'*64)
|
||||
path = exp / 'authorities' / (name + '.json'); write(path, auth); job['authority_file'] = str(path)
|
||||
cyclefile = exp / 'receipts' / (name + '.cycle.json'); cycle = T.read(cyclefile)
|
||||
cycle['source_registration_sha256'] = sha; write(cyclefile, cycle)
|
||||
result = {}
|
||||
if kind in ('brain', 'unchanged', 'updated'): result['checkpoint_manifest_sha256'] = parents[name]['checkpoint_sha256']
|
||||
if kind == 'update':
|
||||
write(out / 'chain-receipt.json', {'synthetic': True}); result['chain_receipt_sha256'] = T.digest(out / 'chain-receipt.json')
|
||||
paths = {key: exp / folder / (name + suffix) for key, folder, suffix in
|
||||
(('process', 'receipts', '.process.json'), ('worker', 'receipts', '.worker.json'), ('job', 'jobs', '.json'))}
|
||||
for p in paths.values(): write(p, {'synthetic': name})
|
||||
verified[name] = dict(name=name, kind=kind, job=job, paths=paths, output=out,
|
||||
output_inventory=T.tree(out), receipt={'result': result, 'environment': {}}, input_pins={},
|
||||
evidence_sha256={str(p): T.digest(p) for p in paths.values()})
|
||||
complete = dict(complete=True, registration_sha256=sha, completed_calls=[c['call_id'] for c in plan['calls']],
|
||||
processes={k: str(v['paths']['process']) for k, v in verified.items()}, parents=parents,
|
||||
scientific_learning_pass_claimed=False, candidate_generated=False)
|
||||
write(exp / 'audit/execution-complete.json', complete)
|
||||
return sha, records, verified
|
||||
|
||||
def test_all_predetermined_calls_compared_and_numeric_failure_not_hidden(self):
|
||||
with tempfile.TemporaryDirectory() as name, ExitStack() as stack:
|
||||
exp = Path(name).resolve() / 'phase4aq-mock'; sha, records, verified = self.fixture(exp)
|
||||
stack.enter_context(patch.object(T, 'EXP', exp))
|
||||
stack.enter_context(patch.object(T, 'N', 1)); stack.enter_context(patch.object(T, 'EDGES', 1))
|
||||
stack.enter_context(patch.object(T.PLAN, 'validate_plan'))
|
||||
stack.enter_context(patch.object(T, '_helpers', return_value=SimpleNamespace(_verify_precision=lambda *a: None)))
|
||||
verifier = stack.enter_context(patch.object(T, 'verify_process', side_effect=lambda n, *args: verified[n]))
|
||||
stack.enter_context(patch.object(T.D, 'load_checkpoint')); stack.enter_context(patch.object(T.D.C, 'load_checkpoint'))
|
||||
stack.enter_context(patch.object(T.B, 'load_record', side_effect=lambda d, **kw: records[str(d)]))
|
||||
stack.enter_context(patch.object(T.B, '_complete')); stack.enter_context(patch.object(T.B, 'close_record'))
|
||||
stack.enter_context(patch.object(T, '_update_check', return_value={'pass_all': True}))
|
||||
live = stack.enter_context(patch.object(T.B, 'compare_boundary', return_value={'numerical_exact': True}))
|
||||
pair = stack.enter_context(patch.object(T, '_pair', return_value={'numerical_exact': True}))
|
||||
pending = dict(conditional_ref_request_queue_exact=True, reference_queue_and_ref_coverage_complete=True,
|
||||
accepted_changed_edge_witness_verified=True)
|
||||
stack.enter_context(patch.object(T, '_pending', return_value=pending))
|
||||
stack.enter_context(patch.object(T, '_lineage', return_value={'pass_all': True}))
|
||||
report = T.audit(sha, save_report=False)
|
||||
self.assertTrue(report['pass_all']); self.assertEqual(report['actual_new_brain_calls'], 23)
|
||||
self.assertEqual(report['actual_new_brain_ticks'], 125200); self.assertEqual(report['actual_processes'], 31)
|
||||
self.assertEqual(verifier.call_count, 31); self.assertEqual(live.call_count, 4); self.assertEqual(pair.call_count, 5)
|
||||
self.assertFalse(report['brain_executed_here']); self.assertFalse(report['learning_pass_claimed'])
|
||||
self.assertFalse((exp / 'audit/numerical-comparison.json').exists())
|
||||
pair.return_value = {'numerical_exact': False}
|
||||
report = T.audit(sha)
|
||||
self.assertEqual(report['status'], 'FAIL-NUMERICAL-OR-LINEAGE'); self.assertFalse(report['pass_all'])
|
||||
self.assertTrue((exp / 'audit/numerical-comparison.json').is_file())
|
||||
with self.assertRaises(FileExistsError): T.audit(sha)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -0,0 +1,281 @@
|
||||
"""Tiny synthetic arrays / temporary read fixtures; no brain or GPU execution."""
|
||||
import copy
|
||||
import csv
|
||||
import json
|
||||
from pathlib import Path
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
import numpy as np
|
||||
|
||||
import boundary_compare as m
|
||||
|
||||
|
||||
Q=m._load('engineering_queue_audit.py',m.PINS['engineering_queue_audit.py'])
|
||||
|
||||
|
||||
def raw(a):return __import__('hashlib').sha256(np.ascontiguousarray(a).tobytes()).hexdigest()
|
||||
|
||||
|
||||
def save(path,value):path.write_text(json.dumps(value,allow_nan=False),encoding='utf-8')
|
||||
|
||||
|
||||
class Fixture:
|
||||
def __init__(self,cut=20,total=61,reject=False,delta=None):
|
||||
self.cut,self.total=cut,total
|
||||
self.graph=dict(ptr=np.array([0,2,4,5,6],np.int64),src=np.array([0,0,1,1,2,3],np.int32),
|
||||
dst=np.array([1,2,2,3,3,0],np.int32),edge_id=np.arange(6,dtype=np.int64),
|
||||
base_weights=np.full(6,.000275,np.float64),apl_mask=np.zeros(6,np.bool_),
|
||||
candidate_edge_id=np.array([0],np.int64),delta_before=np.array([0.],np.float32),
|
||||
delta_after=np.array([-.00275 if delta is None else delta],np.float32))
|
||||
g=self.graph
|
||||
_,_,rows,before,after=m._candidates(g['ptr'],g['src'],g['dst'],g['edge_id'],g['base_weights'],g['apl_mask'],
|
||||
g['candidate_edge_id'],g['delta_before'],g['delta_after'],Q)
|
||||
self.before_sha=m._effective_hash(g['base_weights'],g['apl_mask'],rows,before)
|
||||
self.after_sha=m._effective_hash(g['base_weights'],g['apl_mask'],rows,after)
|
||||
self.effective=g['base_weights'].copy();self.effective[rows]=after
|
||||
pairs=[(0,3),(cut-2,2),(cut-1,0),(cut+23,0),(total-1,2)]
|
||||
if reject:pairs.append((cut+17,1))
|
||||
pairs=sorted(pairs);self.tick=np.array([t for t,n in pairs],np.int32);self.node=np.array([n for t,n in pairs],np.int32)
|
||||
self.requests=np.column_stack((self.tick,self.node,np.ones(len(pairs),np.int32),np.ones(len(pairs),np.int32),np.zeros(len(pairs),np.int32))).astype(np.int64)
|
||||
refs=[];ref=np.zeros(4,np.int32);self.queues=[]
|
||||
for t in range(total):
|
||||
ref=np.maximum(ref-1,0).astype(np.int32);ref[self.node[self.tick==t]]=22;refs.append(ref.copy())
|
||||
sources=self.node[self.tick==t-18] if t>=18 else self.node[:0]
|
||||
qr,_,_=Q._queue(t,t if t<cut else t-cut,sources,ref,g['ptr'],g['dst'],g['edge_id'],self.effective,[])
|
||||
self.queues.append(qr)
|
||||
self.refs=np.asarray(refs)
|
||||
self.v=np.full((total,4),-.052,np.float64)+np.arange(total)[:,None]*np.float64(1e-7)
|
||||
self.g=np.zeros((total,4),np.float64)+np.arange(total)[:,None]*np.float64(1e-6)
|
||||
self.traces={'drive':np.arange(total*2,dtype=np.float32).reshape(total,2)*np.float32(.001),
|
||||
'state':np.arange(total*2,dtype=np.float32).reshape(total,2)*np.float32(.002),
|
||||
'generated':np.arange(total*3,dtype=np.float32).reshape(total,3)*np.float32(.003)}
|
||||
self.traces['applied']=np.zeros((total,3),np.float32);self.traces['applied'][18:]=self.traces['generated'][:-18]
|
||||
self.parent=self.record(0,cut,'reference');self.parent['manifest_sha256']='d'*64
|
||||
self.child=self.record(cut,total,'reference');self.oracle=self.record(0,total,'reference')
|
||||
self.parent['summary']['effective_weights_raw_sha256']=self.before_sha
|
||||
self.child['summary'].update(within_trial_weight_updates=False,checkpoint_continuation_used=True,
|
||||
updated_boundary_schema='conditioning-updated-boundary-v1',parent_checkpoint_manifest_sha256='d'*64,
|
||||
global_next_tick=total,boundary_transition='epoch_update',boundary_authority_sha256='e'*64,global_tick_offset=cut)
|
||||
self.oracle['summary'].update(diagnostic_live_boundary=True,within_trial_weight_updates=True,explicit_weight_switches=1,
|
||||
boundary_tick=cut,restored_from_checkpoint=False,production_backend=False,initial_effective_weights_raw_sha256=self.before_sha)
|
||||
self.oracle['boundary_snapshot']={**{k:self.parent['state'][k].copy() for k in ('v','g','ref','counts')},
|
||||
**{k:self.parent['terminal'][k].copy() for k in ('spike_ring','apl_state','apl_pending')}}
|
||||
self.oracle['boundary_report']=dict(complete=True,boundary_tick=cut,parent_checkpoint_manifest_sha256='d'*64,
|
||||
restore_called=False,initial_state_replaced=False,queues_replaced=False,existing_weights_replaced_once=True,
|
||||
before_effective_sha256=self.before_sha,after_effective_sha256=self.after_sha)
|
||||
self.oracle['oracle_provenance']=dict(schema='conditioning-live-boundary-oracle-v1',complete=True,
|
||||
restore_called=False,prefix_sparse_events_exact=True,learning_pass_claimed=False,authority_sha256='e'*64)
|
||||
|
||||
def record(self,start,stop,mode):
|
||||
selection=(self.tick>=start)&(self.tick<stop);tick=self.tick[selection]-np.int32(start);node=self.node[selection]
|
||||
ring=np.zeros((19,4),np.uint8)
|
||||
if start:
|
||||
for t in range(max(0,start-19),start):ring[t%19,self.node[self.tick==t]]=1
|
||||
ring=ring[(np.arange(19)+start%19)%19].copy()
|
||||
for t in range(stop-start):ring[t%19]=0;ring[t%19,node[tick==t]]=1
|
||||
pending=np.zeros((18,3),np.float32)
|
||||
available=min(stop,18);pending[-available:]=self.traces['generated'][stop-available:stop]
|
||||
state=dict(step=tick,neuron_idx=node,counts=np.bincount(node,minlength=4).astype(np.int32),
|
||||
v=self.v[stop-1].copy(),g=self.g[stop-1].copy(),ref=self.refs[stop-1].copy())
|
||||
req=self.requests[(self.requests[:,0]>=start)&(self.requests[:,0]<stop)].copy();req[:,0]-=start
|
||||
hashes=[dict(tick=t-start,v_sha256=raw(self.v[t]),g_sha256=raw(self.g[t]),ref_sha256=raw(self.refs[t])) for t in range(start,stop)]
|
||||
queues=[self.queues[t][0 if start==0 else 1].copy() for t in range(start,stop)]
|
||||
summary=dict(steps=stop-start,completed_ticks=stop-start,complete=True,pass_all=True,all_finite=True,nodes=4,edges=6,
|
||||
precision='float64',apl_precision='float32',apl_delay_steps=18,diagnostic_mode=mode,
|
||||
within_trial_weight_updates=False,effective_weights_raw_sha256=self.after_sha,checkpoint_continuation_used=start>0,
|
||||
global_tick_offset=start,global_next_tick=stop)
|
||||
return dict(steps=stop-start,global_tick_offset=start,state=state,
|
||||
terminal=dict(spike_ring=ring,apl_state=self.traces['state'][stop-1].copy(),apl_pending=pending,next_tick=np.asarray(stop-start,np.int64)),
|
||||
requests=req,summary=summary,traces={k:v[start:stop].copy() for k,v in self.traces.items()},state_hashes=hashes,queues=queues,
|
||||
terminal_origin='recorded_terminal_queues')
|
||||
|
||||
def compare(self,paired_authorities=None):
|
||||
return m.compare_boundary(self.oracle,self.child,parent=self.parent,
|
||||
expected_before_sha256=self.before_sha,expected_after_sha256=self.after_sha,paired_authorities=paired_authorities)
|
||||
|
||||
def audit(self):
|
||||
return m.audit_changed_pending(self.parent,self.child,**self.graph,input_pins={'synthetic-input-authority':'a'*64})
|
||||
|
||||
|
||||
class ComparisonTests(unittest.TestCase):
|
||||
def test_exact_reference_suffix_and_different_raw_ring_phase(self):
|
||||
f=Fixture();result=f.compare()
|
||||
self.assertTrue(result['numerical_exact'],result['failed_checks'])
|
||||
self.assertTrue(result['suffix_reference_diagnostics_compared'])
|
||||
self.assertFalse(np.array_equal(f.child['terminal']['spike_ring'],f.oracle['terminal']['spike_ring']))
|
||||
self.assertFalse(result['learning_pass_claimed'])
|
||||
self.assertFalse(result['changed_candidate_pending_arrival_coverage_verified'])
|
||||
|
||||
def test_light_reports_only_observed_scope(self):
|
||||
f=Fixture();f.child.update(traces={},state_hashes=None,queues=None);f.child['summary']['diagnostic_mode']='light'
|
||||
result=f.compare();self.assertTrue(result['numerical_exact']);self.assertFalse(result['suffix_reference_diagnostics_compared'])
|
||||
self.assertFalse(result['light_per_tick_identity_claimed'])
|
||||
self.assertNotIn('suffix.state_hashes',result['checks'])
|
||||
|
||||
def test_signed_zero_final_change_is_detected(self):
|
||||
f=Fixture();f.child['state']['g'][0]=0.;f.oracle['state']['g'][0]=-0.
|
||||
f.child['state_hashes'][-1]['g_sha256']=raw(f.child['state']['g'])
|
||||
f.oracle['state_hashes'][-1]['g_sha256']=raw(f.oracle['state']['g'])
|
||||
result=f.compare();self.assertFalse(result['pass_all']);self.assertIn('final.g',result['failed_checks'])
|
||||
|
||||
def test_tick_shift_ref_and_event_counts_are_not_interchangeable(self):
|
||||
f=Fixture();old=int(f.child['state']['step'][0]);f.child['state']['step'][0]-=1
|
||||
f.child['terminal']['spike_ring'][old%19,0]=0
|
||||
f.child['terminal']['spike_ring'][(old-1)%19,0]=1
|
||||
result=f.compare();self.assertFalse(result['numerical_exact']);self.assertIn('suffix.events.absolute_tick',result['failed_checks'])
|
||||
|
||||
def test_reference_missing_history_is_rejected_not_false_pass(self):
|
||||
f=Fixture();f.child['state_hashes']=None
|
||||
with self.assertRaisesRegex(ValueError,'diagnostics missing'):f.compare()
|
||||
|
||||
def test_queue_joint_header_exclusion_is_only_comparison_not_audit(self):
|
||||
f=Fixture();f.child['queues'][17]['joint_sha256']='1'*64
|
||||
self.assertTrue(f.compare()['pass_all'])
|
||||
self.assertFalse(f.audit()['pass_all'])
|
||||
|
||||
def test_wrong_live_prefix_parent_cannot_pass_suffix_only(self):
|
||||
f=Fixture();f.oracle['boundary_snapshot']['g'][0]+=1e-12
|
||||
result=f.compare();self.assertFalse(result['pass_all']);self.assertIn('boundary.live_parent.g',result['failed_checks'])
|
||||
|
||||
def test_original_authority_and_weight_scope_are_checked(self):
|
||||
f=Fixture();f.oracle['oracle_provenance']['authority_sha256']='a'*64
|
||||
self.assertFalse(f.compare()['pass_all'])
|
||||
|
||||
def pair(self,f,changed=None):
|
||||
original={key:{'synthetic':1} for key in m.AUTHORITY_FIELDS}
|
||||
original.update(schema='conditioning-updated-boundary-v1',boundary_id='reference-boundary',diagnostic_mode='reference')
|
||||
other=copy.deepcopy(original);other.update(boundary_id='light-boundary',diagnostic_mode='light')
|
||||
if changed:other.update(changed)
|
||||
pair=(json.dumps(original,sort_keys=True,indent=2).encode(),json.dumps(other,sort_keys=True,indent=2).encode())
|
||||
f.oracle['oracle_provenance']['authority_sha256']=__import__('hashlib').sha256(pair[0]).hexdigest()
|
||||
f.child['summary']['boundary_authority_sha256']=__import__('hashlib').sha256(pair[1]).hexdigest()
|
||||
f.child.update(traces={},state_hashes=None,queues=None);f.child['summary']['diagnostic_mode']='light'
|
||||
return pair
|
||||
|
||||
def test_separately_pinned_ref_light_authorities_allow_only_mode_and_id(self):
|
||||
f=Fixture();pair=self.pair(f)
|
||||
self.assertFalse(f.compare()['pass_all'])
|
||||
result=f.compare(pair);self.assertTrue(result['pass_all'],result['failed_checks'])
|
||||
audit=result['paired_authority_audit'];self.assertTrue(audit['checks']['actual_raw_file_SHA_bound'])
|
||||
self.assertNotEqual(audit['raw_sha256'][0],audit['canonical_sha256'][0])
|
||||
self.assertEqual(audit['common_content_canonical_sha256'][0],audit['common_content_canonical_sha256'][1])
|
||||
|
||||
def test_paired_authority_cannot_change_parent_after_requests_or_registration(self):
|
||||
for key in ('parent','overlay_after','case','registration_sha256','cpu_validation','source_files','frozen_inputs'):
|
||||
with self.subTest(key=key):
|
||||
f=Fixture();pair=self.pair(f,{key:{'different':True}})
|
||||
result=f.compare(pair);self.assertFalse(result['pass_all'])
|
||||
self.assertIn(key,result['paired_authority_audit']['disallowed_different_fields'])
|
||||
|
||||
def test_paired_authority_raw_sha_extra_field_and_duplicate_key_are_rejected(self):
|
||||
f=Fixture();pair=self.pair(f)
|
||||
self.assertFalse(f.compare((pair[0]+b' ',pair[1]))['pass_all'])
|
||||
extra=json.loads(pair[1]);extra['unapproved']=True
|
||||
with self.assertRaisesRegex(ValueError,'exact boundary schema'):f.compare((pair[0],json.dumps(extra).encode()))
|
||||
duplicate=pair[1][:-1]+b',"boundary_id":"duplicate"}'
|
||||
with self.assertRaisesRegex(ValueError,'Duplicate authority'):f.compare((pair[0],duplicate))
|
||||
f=Fixture();f.child['summary']['effective_weights_raw_sha256']='a'*64
|
||||
self.assertFalse(f.compare()['pass_all'])
|
||||
|
||||
|
||||
class CoverageTests(unittest.TestCase):
|
||||
def test_actual_changed_accepted_crossing_witness(self):
|
||||
f=Fixture();result=f.audit();self.assertTrue(result['pass_all'],result['differences'])
|
||||
w=result['coverage']['first_witness'];self.assertEqual(w['global_edge_id'],0)
|
||||
self.assertEqual(w['source_spike_global_tick'],19);self.assertEqual(w['arrival_global_tick'],37)
|
||||
self.assertEqual(w['arrival_child_local_tick'],17);self.assertEqual(w['post_threshold_target_ref'],0)
|
||||
self.assertNotEqual(w['before_weight_f64_le_hex'],w['after_weight_f64_le_hex'])
|
||||
|
||||
def test_fixed18_delay_across_all_nearby_ring_phases(self):
|
||||
for cut in (17,18,19,20,21):
|
||||
with self.subTest(cut=cut):
|
||||
result=Fixture(cut=cut,total=cut+41).audit()
|
||||
self.assertTrue(result['pass_all'],result['differences'])
|
||||
self.assertEqual(result['coverage']['first_witness']['arrival_child_local_tick'],17)
|
||||
|
||||
def test_changed_candidate_without_pending_source_is_incomplete(self):
|
||||
f=Fixture();g=f.graph;g['candidate_edge_id'][0]=2 # source1 never spikes in this fixture
|
||||
_,_,rows,_,after=m._candidates(g['ptr'],g['src'],g['dst'],g['edge_id'],g['base_weights'],g['apl_mask'],
|
||||
g['candidate_edge_id'],g['delta_before'],g['delta_after'],Q)
|
||||
f.child['summary']['effective_weights_raw_sha256']=m._effective_hash(g['base_weights'],g['apl_mask'],rows,after)
|
||||
result=f.audit();self.assertTrue(result['conditional_ref_request_queue_exact'])
|
||||
self.assertEqual(result['changed_effective_numeric_count'],1)
|
||||
self.assertIsNone(result['coverage']['first_witness']);self.assertFalse(result['pass_all'])
|
||||
|
||||
def test_target_spike_same_arrival_tick_rejects_changed_edge(self):
|
||||
f=Fixture(reject=True);result=f.audit()
|
||||
self.assertTrue(result['conditional_ref_request_queue_exact']);self.assertFalse(result['pass_all'])
|
||||
self.assertEqual(result['coverage']['rejected_changed_candidate_crossing_arrivals'],1)
|
||||
self.assertIsNone(result['coverage']['first_witness'])
|
||||
|
||||
def test_zero_delta_and_signed_zero_delta_are_not_changed_edge_coverage(self):
|
||||
for delta in (np.float32(0.),np.float32(-0.)):
|
||||
f=Fixture(delta=delta);result=f.audit()
|
||||
self.assertFalse(result['pass_all']);self.assertEqual(result['changed_effective_numeric_count'],0)
|
||||
self.assertEqual(result['status'],'INCOMPLETE-CHANGED-EDGE-COVERAGE')
|
||||
self.assertEqual(result['changed_delta_bit_count'],1)
|
||||
|
||||
def test_wrong_delta_rejected_against_effective_runtime_hash(self):
|
||||
f=Fixture();f.graph['delta_after'][0]=np.float32(-.003)
|
||||
with self.assertRaisesRegex(ValueError,'effective SHA'):f.audit()
|
||||
|
||||
def test_source_array_shuffle_and_queue_order_shuffle_rejected(self):
|
||||
f=Fixture();f.graph['src'][0],f.graph['src'][2]=f.graph['src'][2],f.graph['src'][0]
|
||||
with self.assertRaisesRegex(ValueError,'CSR ordering'):f.audit()
|
||||
f=Fixture();f.child['queues'][17]['ordered_edge_sha256']='f'*64
|
||||
result=f.audit();self.assertFalse(result['pass_all']);self.assertGreater(result['difference_count'],0)
|
||||
|
||||
def test_wrong_delay_by_one_tick_changes_queue_and_acceptance(self):
|
||||
f=Fixture();f.child['queues'][17],f.child['queues'][18]=f.child['queues'][18],f.child['queues'][17]
|
||||
for t,row in enumerate(f.child['queues']):row['tick']=t
|
||||
self.assertFalse(f.audit()['pass_all'])
|
||||
|
||||
def test_reference_absence_is_incomplete_even_with_computed_witness(self):
|
||||
f=Fixture();f.child.update(traces={},state_hashes=None,queues=None)
|
||||
result=f.audit();self.assertTrue(result['conditional_ref_request_queue_exact'])
|
||||
self.assertIsNotNone(result['coverage']['first_witness']);self.assertFalse(result['accepted_changed_edge_witness_verified'])
|
||||
|
||||
def test_duplicate_or_missing_candidate_and_nonfinite_reject(self):
|
||||
f=Fixture();f.graph['candidate_edge_id'][0]=99
|
||||
with self.assertRaisesRegex(ValueError,'Candidate missing'):f.audit()
|
||||
f=Fixture();f.graph['delta_after'][0]=np.nan
|
||||
with self.assertRaisesRegex(ValueError,'delta after'):f.audit()
|
||||
|
||||
def test_request_acceptance_reconstructed_not_just_copied(self):
|
||||
f=Fixture();f.child['requests'][0,3:]=[0,1]
|
||||
result=f.audit();self.assertFalse(result['pass_all'])
|
||||
self.assertTrue(any(row['field']=='request.acceptance' for row in result['differences']))
|
||||
|
||||
def test_incomplete_summary_is_not_an_array_only_pass(self):
|
||||
f=Fixture();f.child['summary']['complete']=False
|
||||
with self.assertRaisesRegex(ValueError,'summary is incomplete'):f.audit()
|
||||
|
||||
|
||||
class LoaderTests(unittest.TestCase):
|
||||
def test_actual_frozen_loader_accepts_declared_oracle_without_fake_schema(self):
|
||||
f=Fixture()
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
root=Path(tmp);r=f.oracle
|
||||
save(root/'summary.json',r['summary']);np.savez_compressed(root/'state.npz',**r['state'])
|
||||
np.savez_compressed(root/'terminal-queues.npz',**r['terminal'])
|
||||
np.save(root/'apl-pending-tail.float32.npy',r['terminal']['apl_pending'])
|
||||
save(root/'apl-timing-audit.json',{'final_apl_state_u32_bits':r['terminal']['apl_state'].view(np.uint32).tolist()})
|
||||
for name,filename in m.C.TRACE_FILES.items():np.save(root/filename,r['traces'][name])
|
||||
for name,rows in (('queue.jsonl',r['queues']),('tick-state-hashes.jsonl',r['state_hashes'])):
|
||||
(root/name).write_text(''.join(json.dumps(row)+'\n' for row in rows),encoding='utf-8')
|
||||
with (root/'requests.csv').open('w',newline='') as stream:
|
||||
writer=csv.writer(stream);writer.writerow(m.C.REQUEST_FIELDS);writer.writerows(r['requests'])
|
||||
np.savez_compressed(root/'boundary-snapshot.npz',**r['boundary_snapshot'])
|
||||
save(root/'boundary-comparison.json',r['boundary_report']);save(root/'oracle-provenance.json',r['oracle_provenance'])
|
||||
loaded=m.load_record(root,kind='oracle')
|
||||
try:
|
||||
self.assertTrue(loaded['summary']['within_trial_weight_updates'])
|
||||
self.assertFalse(loaded['summary']['production_backend'])
|
||||
result=m.compare_boundary(loaded,f.child,parent=f.parent,
|
||||
expected_before_sha256=f.before_sha,expected_after_sha256=f.after_sha)
|
||||
self.assertTrue(result['pass_all'])
|
||||
finally:m.close_record(loaded)
|
||||
|
||||
|
||||
if __name__=='__main__':unittest.main()
|
||||
@@ -0,0 +1,331 @@
|
||||
"""Independent CPU tests of the new diagnostic oracle, not GPU evidence.
|
||||
|
||||
AST tests consume the real pinned AJ/C/R source. Tiny tensor/helper doubles
|
||||
exercise switch/installation code without claiming a fullgraph simulation,
|
||||
executing any CUDA kernel, or restoring state as an equivalence oracle.
|
||||
"""
|
||||
import ast
|
||||
import copy
|
||||
import hashlib
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import tempfile
|
||||
from types import SimpleNamespace
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
import uuid
|
||||
|
||||
import numpy as np
|
||||
|
||||
import boundary_oracle as b
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
AJ = ROOT / 'apl-timing-lab-v1' / 'gpu_timing.py'
|
||||
|
||||
|
||||
def sha(value):
|
||||
return hashlib.sha256(value).hexdigest()
|
||||
|
||||
|
||||
def bits(value):
|
||||
return np.asarray(value).tobytes()
|
||||
|
||||
|
||||
def fixture(tick=41):
|
||||
"""Raw global-phase rings; the live oracle must NOT rotate spike slots."""
|
||||
v = np.array([-.051, -.047], np.float64)
|
||||
g = np.array([-0., .00013], np.float64)
|
||||
ref, counts = np.array([22, 3], np.int32), np.array([5, 2], np.int32)
|
||||
ring = np.zeros((19, 2), np.uint8)
|
||||
ring[(tick - 1) % 19, 0] = 1
|
||||
ring[(tick - 18) % 19, 1] = 1
|
||||
# Distinct samples across every row expose off-by-one and 18/19 confusion.
|
||||
apl_ring = np.arange(36, dtype=np.float32).reshape(18, 2) / np.float32(16)
|
||||
apl_ring[0, 0] = np.float32(-0.)
|
||||
apl_state = np.array([.5, -0.], np.float32)
|
||||
parent = dict(steps=tick, global_next_tick=tick, fresh=True, manifest_sha256='a' * 64,
|
||||
state={key: value.copy() for key, value in zip(('v', 'g', 'ref', 'counts'), (v, g, ref, counts))},
|
||||
terminal=dict(spike_ring=ring.copy(), apl_state=apl_state.copy(),
|
||||
apl_pending=np.concatenate((apl_ring[tick % 18:], apl_ring[:tick % 18])), next_tick=np.asarray(tick, np.int64)))
|
||||
return parent, [v, g, ref, counts, ring, apl_ring, apl_state]
|
||||
|
||||
|
||||
class Tensor:
|
||||
"""NumPy-only tensor double, including assignment accounting."""
|
||||
def __init__(self, value):
|
||||
self.a = np.array(value, copy=True)
|
||||
self.assignments = []
|
||||
|
||||
def cpu(self): return self
|
||||
def numpy(self): return self.a
|
||||
def numel(self): return self.a.size
|
||||
|
||||
def __getitem__(self, key):
|
||||
return Tensor(self.a[key.a if isinstance(key, Tensor) else key])
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
index = key.a if isinstance(key, Tensor) else key
|
||||
self.assignments.append(np.array(index, copy=True))
|
||||
self.a[index] = value.a if isinstance(value, Tensor) else value
|
||||
|
||||
def __add__(self, other): return Tensor(self.a + (other.a if isinstance(other, Tensor) else other))
|
||||
def __mul__(self, other): return Tensor(self.a * other)
|
||||
|
||||
|
||||
class CanonicalEdgeIdentity:
|
||||
"""No actual fullgraph arrays: only the private test's admission double."""
|
||||
def __len__(self): return 25582938
|
||||
def __getitem__(self, key): return np.asarray(key, dtype=np.int64).copy()
|
||||
|
||||
|
||||
class TinyHelper:
|
||||
@staticmethod
|
||||
def map_installation(base, edges, apl_mask, plan):
|
||||
nz = plan['plastic_delta_mv'] != np.float32(0)
|
||||
rows = plan['edge_id'][nz]
|
||||
# Independent frozen bridge expression; do not invoke oracle helper.
|
||||
expected = np.add(base[rows], np.multiply(plan['plastic_delta_mv'][nz].astype(np.float64), np.float64(.001)))
|
||||
return dict(rows=rows, expected_si=expected, missing_candidate_count=0)
|
||||
|
||||
@staticmethod
|
||||
def expected_hashes(base, apl_mask, mapping):
|
||||
result = base.copy()
|
||||
result[mapping['rows']] = mapping['expected_si']
|
||||
return sha(bits(base)), sha(bits(result))
|
||||
|
||||
@staticmethod
|
||||
def bit_equal(a, c):
|
||||
return a.dtype == c.dtype and a.shape == c.shape and a.tobytes() == c.tobytes()
|
||||
|
||||
|
||||
class BoundaryOracleTests(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
# Use the actual pinned dependency, with no Torch/CUDA import.
|
||||
cls.c = b.frozen()
|
||||
cls.source = AJ.read_bytes()
|
||||
|
||||
def test_real_AJ_hook_rollback_and_entire_original_functions_identical(self):
|
||||
source_before = sha(self.source)
|
||||
derived, audit = b.derive_oracle(self.c, self.source)
|
||||
old_reference, original_audit = self.c.R.derive_ast(self.source, 'reference')
|
||||
loops = [n for n in ast.walk(derived) if isinstance(n, ast.For) and isinstance(n.target, ast.Name) and n.target.id == 'tick']
|
||||
self.assertEqual(len(loops), 1)
|
||||
self.assertEqual(ast.unparse(loops[0].body[0]), b.HOOK)
|
||||
hookless = copy.deepcopy(derived)
|
||||
loop = next(n for n in ast.walk(hookless) if isinstance(n, ast.For) and isinstance(n.target, ast.Name) and n.target.id == 'tick')
|
||||
del loop.body[0]
|
||||
self.assertEqual(self.c.R._dump(hookless), self.c.R._dump(old_reference))
|
||||
# Independently roll back the inherited R edits as well. This reaches
|
||||
# the ACTUAL frozen AJ functions, not merely the adapter's own receipt.
|
||||
loader, run = hookless.body
|
||||
admission = [n for n in ast.walk(loader) if isinstance(n, ast.Compare) and ast.unparse(n) == "0 < steps <= spec['max_steps']"]
|
||||
self.assertEqual(len(admission), 1)
|
||||
admission[0].comparators[-1] = ast.Constant(value=1000)
|
||||
body = next(n for n in run.body if isinstance(n, ast.Try)).body
|
||||
for text in (self.c.R._INSTALL, self.c.R._FINISH):
|
||||
indices = [i for i, n in enumerate(body) if ast.unparse(n) == text]
|
||||
self.assertEqual(len(indices), 1)
|
||||
del body[indices[0]]
|
||||
originals = ast.parse(self.source)
|
||||
original_module = ast.Module(body=[next(n for n in originals.body if isinstance(n, ast.FunctionDef) and n.name == name)
|
||||
for name in ('load_inputs', 'run_gpu')], type_ignores=[])
|
||||
self.assertEqual(self.c.R._dump(hookless), self.c.R._dump(original_module))
|
||||
self.assertEqual(audit['base'], original_audit)
|
||||
self.assertTrue(audit['full_AST_rollback_identical'])
|
||||
self.assertFalse(audit['restore_called'])
|
||||
self.assertFalse(audit['production_backend'])
|
||||
self.assertEqual(sha(self.source), source_before)
|
||||
compile(derived, '<actual-AJ-oracle-CPU-compile-only>', 'exec')
|
||||
|
||||
def test_oracle_has_one_hook_before_all_frozen_tick_operations_and_no_restore(self):
|
||||
tree, _ = b.derive_oracle(self.c, self.source)
|
||||
loop = next(n for n in ast.walk(tree) if isinstance(n, ast.For) and isinstance(n.target, ast.Name) and n.target.id == 'tick')
|
||||
self.assertEqual(ast.unparse(loop.body[1]), 'requests.zero_()')
|
||||
calls = [ast.unparse(n.func) for n in ast.walk(tree) if isinstance(n, ast.Call)]
|
||||
self.assertEqual(calls.count('_oracle.switch'), 1)
|
||||
self.assertFalse(any('restore' in name for name in calls))
|
||||
self.assertFalse(any(isinstance(n, ast.Name) and n.id == '_continuation' for n in ast.walk(tree)))
|
||||
oracle_class = b.runtime_class(self.c)
|
||||
self.assertIs(oracle_class.__bases__[0], self.c.R._Runtime)
|
||||
self.assertFalse(issubclass(oracle_class, self.c.ContinuedRuntime))
|
||||
self.assertFalse(hasattr(oracle_class, 'restore'))
|
||||
self.assertIn('due = ring[(tick - 18) % 19]', ast.unparse(tree))
|
||||
self.assertIn('slot = tick % apl_delay', ast.unparse(tree))
|
||||
|
||||
def test_real_source_pin_rejects_even_whitespace_drift(self):
|
||||
for changed in (self.source + b'\n', self.source.replace(b'tick >= 18', b'tick >= 17')):
|
||||
with self.assertRaisesRegex(ValueError, 'AJ source pin'):
|
||||
b.derive_oracle(self.c, changed)
|
||||
|
||||
def test_frozen_C_pin_and_existing_module_binding_refuse_before_execution(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
path = Path(tmp) / 'tiny.py'
|
||||
path.write_text('VALUE = 17\n', encoding='utf-8')
|
||||
name = 'boundary_oracle_cpu_fixture_' + uuid.uuid4().hex
|
||||
with self.assertRaisesRegex(ValueError, 'Unverified'):
|
||||
b.load(name, path, '0' * 64)
|
||||
self.assertNotIn(name, sys.modules)
|
||||
try:
|
||||
module = b.load(name, path, b.digest(path))
|
||||
self.assertEqual(module.VALUE, 17)
|
||||
with self.assertRaisesRegex(ValueError, 'Unverified'):
|
||||
b.load(name, path, b.digest(path))
|
||||
self.assertIs(sys.modules[name], module)
|
||||
finally:
|
||||
sys.modules.pop(name, None) # Only this test-created tiny module.
|
||||
frozen_path = Path(tmp) / 'runtime_continuation.py'
|
||||
frozen_path.write_text('raise AssertionError("must not execute")\n', encoding='utf-8')
|
||||
with patch.object(b, 'LAB', Path(tmp)), self.assertRaisesRegex(ValueError, 'Unverified'):
|
||||
b.frozen()
|
||||
|
||||
def test_expected_bridge_is_original_base_plus_widened_after_delta_not_old_effective(self):
|
||||
base = np.array([.000275, .000550, -.00011, .0], np.float64)
|
||||
mask = np.array([0, 1], np.int64)
|
||||
before = np.array([-.00275, -.013125], np.float32)
|
||||
after = np.array([-.0055, -.02125], np.float32)
|
||||
old_effective = base[mask] + before.astype(np.float64) * np.float64(.001)
|
||||
expected = np.add(base[mask], np.multiply(after.astype(np.float64), np.float64(.001)))
|
||||
actual = b.expected_candidate_values(base, mask, after)
|
||||
self.assertEqual(bits(actual), bits(expected))
|
||||
self.assertNotEqual(bits(actual), bits(old_effective + after.astype(np.float64) * np.float64(.001)))
|
||||
self.assertNotEqual(bits(actual), bits(base[mask] + (after * np.float32(.001)).astype(np.float64)))
|
||||
zero = np.array([0., -0.], np.float32)
|
||||
self.assertEqual(bits(b.expected_candidate_values(base, mask, zero)), bits(base[mask]))
|
||||
self.assertEqual(bits(base), bits(np.array([.000275, .000550, -.00011, .0], np.float64)))
|
||||
|
||||
def test_candidate_bridge_rejects_dtype_bounds_order_sign_and_nonfinite(self):
|
||||
base, mask, delta = np.array([.01, .02], np.float64), np.array([0, 1], np.int64), np.array([-.001, -.002], np.float32)
|
||||
cases = [(base.astype(np.float32), mask, delta), (base, mask.astype(np.int32), delta),
|
||||
(base, mask, delta.astype(np.float64)), (base, mask[::-1].copy(), delta),
|
||||
(base, np.array([0, 0], np.int64), delta), (base, np.array([-1, 1], np.int64), delta),
|
||||
(base, np.array([0, 2], np.int64), delta), (base, mask, np.array([np.nan, 0.], np.float32)),
|
||||
(base, mask, np.array([np.inf, 0.], np.float32)), (base, mask, np.array([.01, 0.], np.float32)),
|
||||
(base, mask, np.array([-20., 0.], np.float32)), (np.array([np.inf, .02], np.float64), mask, delta)]
|
||||
for args in cases:
|
||||
with self.subTest(args=[(a.dtype.str, a.tolist()) for a in args]), self.assertRaises(ValueError):
|
||||
b.expected_candidate_values(*args)
|
||||
|
||||
def test_live_raw_boundary_checks_18_and_19_phases_without_rotating_spike_ring(self):
|
||||
for tick in (1, 5, 17, 18, 19, 20, 35, 36, 37, 38, 41, 1200):
|
||||
parent, arrays = fixture(tick)
|
||||
before = [bits(value) for value in arrays]
|
||||
actual, checks = b.boundary_arrays(parent, tick, *arrays)
|
||||
self.assertTrue(all(checks.values()))
|
||||
self.assertEqual(bits(actual['spike_ring']), bits(arrays[4]))
|
||||
order = np.array([(tick + i) % 18 for i in range(18)])
|
||||
self.assertEqual(bits(actual['apl_pending']), bits(arrays[5][order]))
|
||||
self.assertEqual(before, [bits(value) for value in arrays])
|
||||
if tick % 19:
|
||||
wrong = list(arrays); wrong[4] = self.c.rotate_spike_ring(arrays[4], tick)
|
||||
with self.subTest(tick=tick), self.assertRaisesRegex(ValueError, 'spike_ring'):
|
||||
b.boundary_arrays(parent, tick, *wrong)
|
||||
|
||||
def test_boundary_rejects_rawbit_dtype_queue_clock_or_counts_corruption(self):
|
||||
for variant in ('negative_zero_g', 'negative_zero_apl', 'g_dtype', 'v_shape', 'counts', 'spike', 'apl_phase', 'clock', 'continued', 'booltick'):
|
||||
parent, arrays = fixture(41)
|
||||
tick = 41
|
||||
if variant == 'negative_zero_g': arrays[1][0] = 0.
|
||||
if variant == 'negative_zero_apl': arrays[6][1] = np.float32(0.)
|
||||
if variant == 'g_dtype': arrays[1] = arrays[1].astype(np.float32)
|
||||
if variant == 'v_shape': arrays[0] = arrays[0][:-1]
|
||||
if variant == 'counts': arrays[3][0] += 1
|
||||
if variant == 'spike': arrays[4][2, 0] ^= 1
|
||||
if variant == 'apl_phase': arrays[5] = np.roll(arrays[5], 1, axis=0)
|
||||
if variant == 'clock': parent['global_next_tick'] += 1
|
||||
if variant == 'continued': parent['fresh'] = False
|
||||
if variant == 'booltick': tick = True
|
||||
with self.subTest(variant=variant), self.assertRaises(ValueError): b.boundary_arrays(parent, tick, *arrays)
|
||||
|
||||
def runtime_fixture(self, out):
|
||||
parent, arrays = fixture(41)
|
||||
base = np.array([.000275, .000550, -.00011, .0], np.float64)
|
||||
mask = np.array([0, 1], np.int64)
|
||||
old = dict(edge_id=mask, plastic_delta_mv=np.array([-.00275, -.013125], np.float32))
|
||||
new = dict(edge_id=mask, plastic_delta_mv=np.array([-.0055, -.02125], np.float32))
|
||||
helper = TinyHelper()
|
||||
apl_mask = SimpleNamespace(sum=lambda: 5845)
|
||||
prior = helper.map_installation(base, None, apl_mask, old)
|
||||
following = helper.map_installation(base, None, apl_mask, new)
|
||||
before_sha = helper.expected_hashes(base, apl_mask, prior)[1]
|
||||
after_sha = helper.expected_hashes(base, apl_mask, following)[1]
|
||||
parent['summary'] = {'effective_weights_raw_sha256': before_sha}
|
||||
saved = {}
|
||||
# Only these diagnostic I/O and GPU-observer dependencies are doubles;
|
||||
# the actual Oracle install/switch implementation is executed below.
|
||||
r = SimpleNamespace(_Runtime=self.c.R._Runtime, FiniteObserver=lambda *_: object(),
|
||||
_copy_input=lambda *_: None, digest=lambda p: sha(str(p).encode()),
|
||||
_save=lambda p, value: saved.__setitem__(Path(p).name, value))
|
||||
cls = b.runtime_class(SimpleNamespace(R=r))
|
||||
boundary = dict(parent=parent, after_plan=new,
|
||||
value=dict(expected_effective_weight_before_sha256=before_sha, expected_effective_weight_after_sha256=after_sha),
|
||||
paths={key: out / key for key in ('before_overlay', 'before_manifest', 'after_overlay', 'after_manifest')})
|
||||
obj = cls('reference', {'max_steps': 60, 'steps': 60}, helper, old, {}, {},
|
||||
SimpleNamespace(int64=np.int64, float64=np.float64), out / 'old.npz', out / 'old.json', boundary=boundary)
|
||||
weights = Tensor(base)
|
||||
graph = dict(nodes=range(166700), edge_id=CanonicalEdgeIdentity(), weights=base)
|
||||
upload = lambda value, dtype: Tensor(np.asarray(value, dtype=dtype))
|
||||
args = [Tensor(value) for value in arrays[:-1]] + [SimpleNamespace(state=Tensor(arrays[-1]))]
|
||||
return obj, weights, graph, apl_mask, upload, args, saved, base, new
|
||||
|
||||
def test_actual_install_then_one_switch_replaces_base_plus_after_and_never_state_or_queues(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
out = Path(tmp)
|
||||
obj, weights, graph, mask, upload, args, saved, base, new = self.runtime_fixture(out)
|
||||
obj.install(weights, graph, mask, upload, out, {}, 'CPU-double')
|
||||
before = weights.a.copy()
|
||||
state_before = [bits(x.a) for x in args[:-1]] + [bits(args[-1].state.a)]
|
||||
obj.switch(41, weights, *args, out)
|
||||
expected = base.copy()
|
||||
expected[new['edge_id']] = np.add(base[new['edge_id']], np.multiply(new['plastic_delta_mv'].astype(np.float64), np.float64(.001)))
|
||||
self.assertEqual(bits(weights.a), bits(expected))
|
||||
wrong = before.copy(); wrong[new['edge_id']] += new['plastic_delta_mv'].astype(np.float64) * np.float64(.001)
|
||||
self.assertNotEqual(bits(weights.a), bits(wrong))
|
||||
self.assertEqual(bits(weights.a[2:]), bits(before[2:]))
|
||||
self.assertEqual(obj.switches, 1)
|
||||
self.assertEqual(obj.installations, 1)
|
||||
self.assertEqual(state_before, [bits(x.a) for x in args[:-1]] + [bits(args[-1].state.a)])
|
||||
self.assertFalse(saved['boundary-comparison.json']['restore_called'])
|
||||
self.assertFalse(saved['boundary-comparison.json']['queues_replaced'])
|
||||
self.assertEqual(len(weights.assignments), 2) # One old-overlay install, one replacement.
|
||||
with np.load(out / 'boundary-snapshot.npz', allow_pickle=False) as recorded:
|
||||
self.assertEqual(bits(recorded['g']), state_before[1])
|
||||
with self.assertRaisesRegex(ValueError, 'repeated'): obj.switch(41, weights, *args, out)
|
||||
with self.assertRaisesRegex(ValueError, 'one intact'): obj.install(weights, graph, mask, upload, out, {}, 'CPU-double')
|
||||
|
||||
def test_switch_refuses_wrong_time_or_preexisting_weight_state_drift(self):
|
||||
for variant in ('before_install', 'wrong_tick', 'weight_drift', 'state_drift', 'after_hash'):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
out = Path(tmp)
|
||||
obj, weights, graph, mask, upload, args, _, _, _ = self.runtime_fixture(out)
|
||||
obj.install(weights, graph, mask, upload, out, {}, 'CPU-double')
|
||||
tick = 41
|
||||
if variant == 'before_install': obj.installations = 0
|
||||
if variant == 'wrong_tick': tick = 42
|
||||
if variant == 'weight_drift': weights.a[3] = .0001
|
||||
if variant == 'state_drift': args[1].a[0] = 0.
|
||||
if variant == 'after_hash': obj.after_sha = 'f' * 64
|
||||
with self.subTest(variant=variant), self.assertRaises(ValueError): obj.switch(tick, weights, *args, out)
|
||||
self.assertEqual(obj.switches, 0)
|
||||
self.assertFalse((out / 'boundary-snapshot.npz').exists())
|
||||
|
||||
def test_finish_requires_the_boundary_and_summary_discloses_diagnostic_scope(self):
|
||||
cls = b.runtime_class(self.c)
|
||||
obj = object.__new__(cls)
|
||||
obj.switches = 0
|
||||
with self.assertRaisesRegex(ValueError, 'did not execute'): obj.finish()
|
||||
obj.mode = 'reference'; obj.spec = dict(max_steps=100, steps=100)
|
||||
obj.result = {'first_failure_tick': -1}; obj.boundary_tick = 41; obj.switches = 1
|
||||
obj.after_sha = 'a' * 64; obj.before_sha = 'b' * 64
|
||||
result = obj.summary({'complete': True, 'effective_weights_raw_sha256': 'b' * 64, 'learning': False})
|
||||
self.assertTrue(result['within_trial_weight_updates'])
|
||||
self.assertFalse(result['production_backend'])
|
||||
self.assertFalse(result['restored_from_checkpoint'])
|
||||
self.assertFalse(result['learning_pass_claimed'])
|
||||
self.assertEqual(result['effective_weights_raw_sha256'], 'a' * 64)
|
||||
self.assertEqual(result['initial_effective_weights_raw_sha256'], 'b' * 64)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -0,0 +1,284 @@
|
||||
"""CPU fixtures and frozen-source checks; never sample or run a brain."""
|
||||
from copy import deepcopy
|
||||
import hashlib
|
||||
import importlib.util
|
||||
import json
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
import numpy as np
|
||||
import boundary_plan as B
|
||||
|
||||
|
||||
SOURCE = Path(__file__).resolve().parent.parent
|
||||
EVIDENCE = SOURCE.parent / 'reports/phase4ap-publication/evidence'
|
||||
if not EVIDENCE.is_dir():
|
||||
EVIDENCE = SOURCE.parents[1] / 'registry/phase4ap-conditioning-interface-v2/evidence'
|
||||
OUTPUT_ROOT = '/data/digital-drosophila/experiments/boundary-plan-fixture'
|
||||
|
||||
|
||||
def load_source(name, path):
|
||||
spec = importlib.util.spec_from_file_location(name, path)
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
return module
|
||||
|
||||
|
||||
class BoundaryPlanTests(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.template = json.loads((EVIDENCE / 'cases/D1--reference--epoch-001/spec.json').read_text())
|
||||
cls.registry = load_source('boundary_test_seed_registry', SOURCE/'olfactory-conditioning-lab-v1/seed_registry.py')
|
||||
with patch.dict(sys.modules, {'seed_registry': cls.registry}):
|
||||
cls.trial_plan = load_source('boundary_test_trial_plan', SOURCE/'olfactory-conditioning-lab-v1/trial_plan.py')
|
||||
|
||||
def setUp(self):
|
||||
self.plan = B.build_plan()
|
||||
self.calls = {c['call_id']: c for c in self.plan['calls']}
|
||||
|
||||
def spec(self, call):
|
||||
return B.derive_case_spec(self.template, call, budget_root=OUTPUT_ROOT)
|
||||
|
||||
def test_source_protocol_and_template_pins_match_actual_local_bytes(self):
|
||||
for path, pin in B.SOURCE_PINS.items():
|
||||
self.assertEqual(hashlib.sha256((SOURCE/path).read_bytes()).hexdigest(), pin, path)
|
||||
for path, pin in B.AP_ANCHORS.items():
|
||||
self.assertEqual(hashlib.sha256((EVIDENCE/path).read_bytes()).hexdigest(), pin, path)
|
||||
for arm, pin in B.PARENT_PINS.items():
|
||||
raw = (EVIDENCE/f'runs/{arm}--reference--epoch-001/checkpoint-manifest.json').read_bytes()
|
||||
self.assertEqual(hashlib.sha256(raw).hexdigest(), pin)
|
||||
self.assertEqual(B._sha(self.template), B.TEMPLATE_PAYLOAD_SHA256)
|
||||
|
||||
def test_exact_inventory_ticks_children_and_no_execution_claim(self):
|
||||
self.assertTrue(B.validate_plan(self.plan))
|
||||
self.assertEqual(len(self.calls), 23)
|
||||
self.assertEqual(sum(c['steps'] for c in self.calls.values()), 125200)
|
||||
self.assertEqual(len({c['case_group'] for c in self.calls.values()}), 17)
|
||||
self.assertEqual(len(self.plan['imported_parents']), 3)
|
||||
self.assertEqual(len(self.plan['cpu_children']), 7)
|
||||
self.assertEqual(self.plan['counts']['total_children'], 23+7+1)
|
||||
self.assertEqual(self.plan['sampler_child']['uniform_batch_calls'], 2)
|
||||
self.assertEqual(self.plan['sampler_child']['execution'], 'GPU_private_generator')
|
||||
self.assertIsNone(self.plan['counts']['raw_uniform_draw_count'])
|
||||
for key in ('brain_executed', 'inputs_sampled', 'acquisition_executed', 'full_retention_experiment',
|
||||
'scientific_learning_claimed', 'external_identity_verified_here', 'execution_authorized'):
|
||||
self.assertIs(self.plan[key], False)
|
||||
|
||||
def test_plan_reconstruction_rejects_mutations_including_booleans(self):
|
||||
mutations = [lambda p: p['calls'][0].update(steps=999),
|
||||
lambda p: p['counts'].update(new_brain_calls=20),
|
||||
lambda p: p['calls'][-1].update(parent='D1--probe--t1--A'),
|
||||
lambda p: p['calls'][-1].update(neural_reset=True),
|
||||
lambda p: p['calls'][2].update(overlay_before_role='AP.initial_overlay'),
|
||||
lambda p: p['mechanical_update'].update(trace_backend='numpy'),
|
||||
lambda p: p['source_sha256'].update({'conditioning-interface-v2/PROTOCOL.md': 'a'*64}),
|
||||
lambda p: p.update(execution_authorized=0)]
|
||||
for mutate in mutations:
|
||||
plan = deepcopy(self.plan)
|
||||
mutate(plan)
|
||||
with self.assertRaises(ValueError):
|
||||
B.validate_plan(plan)
|
||||
|
||||
def test_seeds_are_exact_existing_evaluation_streams_not_training_streams(self):
|
||||
streams = B.evaluation_seeds()
|
||||
for cue, row in streams.items():
|
||||
key = self.trial_plan._input_key(B.BLOCK, 'evaluation', cue, 0, 'base-probe')
|
||||
seed, digest = self.registry.seed_for(B.MASTER, 'evaluation', key)
|
||||
self.assertEqual(row['key'], list(key))
|
||||
self.assertEqual((row['seed'], row['derivation_sha256']), (seed, digest))
|
||||
self.assertEqual(row['stream_id'], self.trial_plan._stream_id(B.MASTER, 'evaluation', key))
|
||||
train_seed, _ = self.registry.seed_for(B.MASTER, 'training', key)
|
||||
self.assertNotEqual(seed, train_seed)
|
||||
self.assertGreater(seed, 2**32)
|
||||
self.assertLess(seed, 2**63)
|
||||
self.assertEqual({self.spec(f'D1--probe--{t}--{cue}')['cs_input_seed'] for t in ('t0','t1','t10')}, {seed})
|
||||
self.assertNotEqual(streams['A']['seed'], streams['B']['seed'])
|
||||
|
||||
def test_plan_and_derivation_never_sample(self):
|
||||
with patch('numpy.random.default_rng', side_effect=AssertionError('sampling forbidden')), \
|
||||
patch('numpy.random.uniform', side_effect=AssertionError('sampling forbidden')):
|
||||
B.build_plan()
|
||||
B.evaluation_seeds()
|
||||
for call in self.calls:
|
||||
self.spec(call)
|
||||
|
||||
def test_continuous_idle_clock_and_probe_fork_no_feedback(self):
|
||||
first, second = self.calls['D1--idle--1s'], self.calls['D1--idle--9s']
|
||||
self.assertEqual((first['steps'], first['global_tick_offset'], first['global_next_tick']), (10000,1200,11200))
|
||||
self.assertEqual((second['steps'], second['global_tick_offset'], second['global_next_tick']), (90000,11200,101200))
|
||||
self.assertEqual(second['parent'], first['call_id'])
|
||||
self.assertEqual((first['transition'], second['transition']), ('epoch_update','idle'))
|
||||
for t, parent, tick in (('t0','AP.D1.reference.epoch001',1200),
|
||||
('t1',first['call_id'],11200), ('t10',second['call_id'],101200)):
|
||||
for cue in ('A','B'):
|
||||
probe = self.calls[f'D1--probe--{t}--{cue}']
|
||||
self.assertEqual((probe['parent'],probe['global_tick_offset'],probe['steps']), (parent,tick,1200))
|
||||
self.assertTrue(probe['probe_fork_discard'])
|
||||
for key in ('feedback_to_idle','neural_reset','US','plastic_update'):
|
||||
self.assertIs(probe[key], False)
|
||||
self.assertFalse(any('--probe--' in (c['parent'] or '') for c in self.calls.values()))
|
||||
|
||||
def test_template_keydiff_preserves_model_APL_delay_and_reset(self):
|
||||
saved = deepcopy(self.template)
|
||||
for name in self.calls:
|
||||
spec = self.spec(name)
|
||||
common = set(spec) & set(saved)
|
||||
changed = {key for key in common if spec[key] != saved[key]}
|
||||
self.assertLessEqual(changed, B.CASE_CHANGED_KEYS | B.STALE_INPUT_KEYS)
|
||||
self.assertLessEqual(set(spec)-set(saved), B.CASE_ADDED_KEYS)
|
||||
self.assertLessEqual(set(saved)-set(spec), B.STALE_INPUT_KEYS)
|
||||
for key in ('model','apl','apl_delay_steps','apl_precision','precision','seed','dt_ms',
|
||||
'graph_dir','apl_bundle_dir','coefficients_path','legacy_apl_worker','kind'):
|
||||
self.assertEqual(spec[key], saved[key], (name,key))
|
||||
self.assertEqual(spec['max_steps'], spec['steps'])
|
||||
self.assertEqual(spec['duration_ms'], spec['steps'] * saved['dt_ms'])
|
||||
self.assertEqual(self.template, saved)
|
||||
|
||||
def test_shared_ref_light_oldC_case_groups_produce_identical_specs(self):
|
||||
for arm in ('D1','D0','frozen','mechanical'):
|
||||
ref = self.spec(f'{arm}--updated--reference')
|
||||
self.assertEqual(ref, self.spec(f'{arm}--updated--light'))
|
||||
if arm != 'mechanical':
|
||||
self.assertEqual(ref['name'], f'AP-{arm}-suffix')
|
||||
if arm in ('D0','frozen'):
|
||||
self.assertEqual(ref, self.spec(f'{arm}--old-C--reference'))
|
||||
|
||||
def test_nonolfactory_cases_remove_stale_odor_metadata(self):
|
||||
for name, call in self.calls.items():
|
||||
spec = self.spec(name)
|
||||
if 'cue' not in call:
|
||||
self.assertTrue(B.STALE_INPUT_KEYS.isdisjoint(spec), name)
|
||||
else:
|
||||
for key in ('odor_id','rate_sum_hz','source_panel_row','source_panel_split','target_count','expected_CS_requests'):
|
||||
self.assertNotIn(key, spec)
|
||||
self.assertEqual(spec['CS_window'], [0,1000])
|
||||
|
||||
def test_oracle_is_fresh_diagnostic_one_switch_not_restore(self):
|
||||
for arm in ('D1','mechanical'):
|
||||
row = self.calls[f'{arm}--live-oracle']
|
||||
spec = self.spec(row['call_id'])
|
||||
self.assertIsNone(row['parent'])
|
||||
self.assertEqual(row['steps'], 2200)
|
||||
self.assertEqual(row['global_tick_offset'], 0)
|
||||
self.assertIs(row['restore_used'], False)
|
||||
self.assertIs(spec['within_trial_weight_updates'], True)
|
||||
self.assertEqual(spec['diagnostic_boundary_tick'], 1200)
|
||||
self.assertIs(spec['scientific_learning_claimed'], False)
|
||||
self.assertEqual(self.calls['D1--live-oracle']['overlay_before_role'], 'AP.D1.reference.epoch001.recorded_overlay')
|
||||
for name, row in self.calls.items():
|
||||
if row['runner'] != 'boundary_oracle':
|
||||
self.assertIs(self.spec(name)['within_trial_weight_updates'], False)
|
||||
|
||||
def test_mechanical_before_is_registration_original_zero_not_D0_output(self):
|
||||
registration = json.loads((EVIDENCE/'protocol/preregistered.json').read_text())
|
||||
initial = self.plan['initial_overlay']
|
||||
self.assertEqual(initial['role'], 'AP.initial_overlay')
|
||||
for role in ('overlay_file','overlay_manifest'):
|
||||
self.assertEqual(initial[role]['path'], registration['initial_overlay'][role])
|
||||
self.assertEqual(initial[role]['sha256'], registration['input_sha256'][initial[role]['path']])
|
||||
self.assertEqual(self.calls['mechanical--fresh-parent']['overlay_after_role'], initial['role'])
|
||||
self.assertFalse(self.calls['mechanical--fresh-parent']['inherited_learned_delta'])
|
||||
update = self.plan['mechanical_update']
|
||||
self.assertEqual((update['steps'],update['us_tick'],update['d_command'],update['trace_backend']), (1200,1199,1.0,'torch'))
|
||||
self.assertEqual(update['before_overlay_role'], initial['role'])
|
||||
|
||||
def test_template_drift_unknown_calls_and_bad_output_roots_rejected(self):
|
||||
wrong = deepcopy(self.template)
|
||||
wrong['model']['threshold_mv'] = -44.0
|
||||
with self.assertRaises(ValueError):
|
||||
B.derive_case_spec(wrong,'D1--updated--reference',budget_root=OUTPUT_ROOT)
|
||||
with self.assertRaises(ValueError):
|
||||
self.spec('unregistered-extra-call')
|
||||
for root in ('relative','/',B.AP_ROOT,B.AP_ROOT+'/child','/data','/tmp/../test'):
|
||||
with self.assertRaises(ValueError):
|
||||
B.derive_case_spec(self.template,'D1--updated--reference',budget_root=root)
|
||||
|
||||
def test_budgets_are_fixed_stop_proposals_not_trial_shortening(self):
|
||||
budget = self.plan['budget_proposal']
|
||||
self.assertEqual((budget['output_bytes'],budget['free_reserve_bytes']), (4*2**30,10*2**30))
|
||||
self.assertEqual((budget['child_timeout_seconds'],budget['workflow_timeout_seconds']), (1800,7200))
|
||||
self.assertFalse(budget['approved'])
|
||||
self.assertIn('never_shorten_trial_or_change_gate', budget['on_limit'])
|
||||
|
||||
def test_performance_slot_replays_natural_AP_input_with_full_fresh_cycle(self):
|
||||
row = self.calls['performance--natural-light-fresh']
|
||||
self.assertEqual((row['diagnostic_mode'],row['steps'],row['global_tick_offset']), ('light',1200,0))
|
||||
self.assertIsNone(row['parent'])
|
||||
self.assertEqual(row['input_policy'],'replay_AP_D1_epoch001_input')
|
||||
self.assertEqual(row['overlay_after_role'],'AP.D1.reference.epoch001.recorded_overlay')
|
||||
self.assertFalse(row['new_learning'])
|
||||
self.assertFalse(row['input_sampled'])
|
||||
update = self.plan['performance_update']
|
||||
self.assertEqual((update['us_tick'],update['d_command'],update['trace_backend']), (900,1.0,'torch'))
|
||||
self.assertEqual(update['required_regression'],['all_events','final_state','delta_after'])
|
||||
names = list(self.calls)
|
||||
self.assertLess(names.index(row['call_id']), names.index('mechanical--fresh-parent'))
|
||||
|
||||
def test_fresh_performance_probe_is_not_retention_continuation(self):
|
||||
name = 'performance--evaluation-A-light-fresh'
|
||||
row = self.calls[name]
|
||||
self.assertEqual((row['runner'],row['steps'],row['global_tick_offset']), ('fresh_probe',1200,0))
|
||||
self.assertEqual(row['diagnostic_mode'],'light')
|
||||
self.assertIsNone(row['parent'])
|
||||
self.assertTrue(row['neural_reset'])
|
||||
self.assertEqual(row['overlay_after_role'],'AP.initial_overlay')
|
||||
for key in ('US','plastic_update','feedback_to_idle'):
|
||||
self.assertIs(row[key],False)
|
||||
spec = self.spec(name)
|
||||
self.assertEqual(spec['cs_input_seed'],B.evaluation_seeds()['A']['seed'])
|
||||
self.assertNotIn('parent_checkpoint_manifest_sha256',spec)
|
||||
names = list(self.calls)
|
||||
self.assertEqual(names.index(name),names.index('performance--natural-light-fresh')+1)
|
||||
self.assertNotEqual(row['case_group'],self.calls['D1--probe--t0--A']['case_group'])
|
||||
|
||||
|
||||
class MechanicalRequestTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.mapping = dict(edge_id=np.arange(B.CANDIDATES,dtype=np.int64),
|
||||
source_neuron_idx=np.full(B.CANDIDATES,33,dtype=np.int32),
|
||||
target_neuron_idx=np.full(B.CANDIDATES,900,dtype=np.int32),
|
||||
target_compartment_verbatim=np.full(B.CANDIDATES,'other',dtype='U8'))
|
||||
self.mapping['target_compartment_verbatim'][[4,700]] = B.COMPARTMENT
|
||||
self.mapping['source_neuron_idx'][[0,4,700]] = [1,21,7]
|
||||
self.dan = np.array([101,102,104,108],dtype=np.int32)
|
||||
self.binding = dict(candidate_map_sha256='1'*64,pam15_membership_sha256='2'*64)
|
||||
|
||||
def run_request(self):
|
||||
return B.mechanical_requests(self.mapping,self.dan,identity_binding=self.binding)
|
||||
|
||||
def test_single_minimum_matching_KC_plus_four_DAN_last_tick(self):
|
||||
before = {key:a.copy() for key,a in self.mapping.items()}
|
||||
request, audit = self.run_request()
|
||||
np.testing.assert_array_equal(request['tick'], np.full(5,1199,dtype=np.int32))
|
||||
np.testing.assert_array_equal(request['neuron_idx'], np.array([7,101,102,104,108],dtype=np.int32))
|
||||
self.assertEqual(audit['selected_KC_source_neuron_idx'], 7)
|
||||
self.assertFalse(audit['external_identity_verified_here'])
|
||||
self.assertFalse(audit['accepted_spikes_verified'])
|
||||
self.assertFalse(audit['olfactory_input'])
|
||||
for key in self.mapping:
|
||||
np.testing.assert_array_equal(self.mapping[key],before[key])
|
||||
self.dan[0] = 100
|
||||
self.assertEqual(request['neuron_idx'][1],101)
|
||||
|
||||
def test_array_and_identity_schema_mutations_fail_closed(self):
|
||||
mutations = [lambda: self.mapping.update(edge_id=self.mapping['edge_id'].astype(np.int32)),
|
||||
lambda: self.mapping['edge_id'].__setitem__(1,0),
|
||||
lambda: self.mapping.update(source_neuron_idx=self.mapping['source_neuron_idx'][:-1]),
|
||||
lambda: self.mapping['source_neuron_idx'].__setitem__(0,-1),
|
||||
lambda: self.mapping['target_compartment_verbatim'].__setitem__(slice(None),'y5B2a'),
|
||||
lambda: setattr(self,'dan',self.dan.astype(np.int64)),
|
||||
lambda: self.dan.__setitem__(1,101),
|
||||
lambda: setattr(self,'dan',self.dan[::-1]),
|
||||
lambda: self.dan.__setitem__(0,7),
|
||||
lambda: self.binding.update(pam15_membership_sha256='not-authenticated')]
|
||||
for mutation in mutations:
|
||||
self.setUp()
|
||||
mutation()
|
||||
with self.assertRaises(ValueError):
|
||||
self.run_request()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -0,0 +1,82 @@
|
||||
"""Source/API and synthetic orchestration tests; never actual CUDA sampling."""
|
||||
import copy
|
||||
import hashlib
|
||||
import importlib.util
|
||||
import json
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import tempfile
|
||||
import types
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
import numpy as np
|
||||
import boundary_sampler as S
|
||||
|
||||
|
||||
class SamplerTests(unittest.TestCase):
|
||||
def test_actual_frozen_dependency_pins(self):
|
||||
for name,sha in S.PINS.items():
|
||||
with self.subTest(name=name):self.assertEqual(S.A.digest(S.LAB/name),sha)
|
||||
|
||||
def test_real_sampler_signature_lazy_GPU_and_request_window(self):
|
||||
raw=(S.LAB/'conditioning_inputs.py').read_bytes()
|
||||
module=types.ModuleType('_ci_cpu_fixture');exec(compile(raw,str(S.LAB/'conditioning_inputs.py'),'exec'),module.__dict__)
|
||||
import inspect
|
||||
self.assertEqual(list(inspect.signature(module.generate_cs_requests).parameters),
|
||||
['targets','rates_hz','seed','steps','cs_start_tick','cs_stop_tick','device','max_uniform_draws','dt_ms'])
|
||||
targets=np.array([5,2],np.int32);forced=np.ones((1200,2),np.bool_)
|
||||
result=module.requests_from_forced(forced,targets,cs_start_tick=0,cs_stop_tick=1000)
|
||||
self.assertEqual(len(result['requests']['tick']),2000)
|
||||
self.assertEqual(int(result['requests']['tick'].max()),999)
|
||||
self.assertTrue(np.array_equal(result['requests']['neuron_idx'][:2],np.array([2,5],np.int32)))
|
||||
|
||||
def run_fixture(self,*,mutate_seed=False):
|
||||
"""Fake sampler is intentionally NOT a stochastic or neural validation."""
|
||||
with tempfile.TemporaryDirectory() as td:
|
||||
root=Path(td).resolve();(root/'protocol').mkdir();(root/'inputs/static').mkdir(parents=True);(root/'runs').mkdir()
|
||||
regfile=root/'protocol/preregistered.json';full=root/'full.json';full.write_text('{}')
|
||||
plan=S.PLAN.build_plan();tables={};streams={};calls=[]
|
||||
for cue in ('A','B'):
|
||||
tables[cue]=dict(targets=np.array([5,2],np.int32),rates_hz=np.array([10.,20.],np.float32))
|
||||
with (root/f'inputs/static/{cue}-rates.npz').open('wb') as f:np.savez(f,**tables[cue])
|
||||
stream=copy.deepcopy(plan['evaluation_streams'][cue]);stream['semantic_key']=stream.pop('key')
|
||||
if mutate_seed and cue=='B':stream['seed']+=1
|
||||
streams[(S.PLAN.BLOCK,cue)]=stream
|
||||
reg=dict(schema='conditioning-execution-registration-v1',plan=plan,source_sha256={},prepared_file_sha256={},
|
||||
input_sha256={str(S.LAB/n):sha for n,sha in S.PINS.items()},original_full_plan=S.A.pin(full))
|
||||
regfile.write_text(json.dumps(reg))
|
||||
ci=types.ModuleType('conditioning_inputs');i=types.ModuleType('conditioning_preflight_inputs');ep=types.ModuleType('evaluation_plan')
|
||||
i.load_rate_tables=lambda root:dict(tables=tables)
|
||||
ep._streams=lambda full:streams
|
||||
def generate(targets,rates,**kw):
|
||||
calls.append(kw)
|
||||
self.assertEqual(kw['steps'],1200);self.assertEqual(kw['cs_start_tick'],0)
|
||||
self.assertEqual(kw['cs_stop_tick'],1000);self.assertEqual(kw['max_uniform_draws'],2400)
|
||||
return dict(requests=dict(tick=np.array([0,999],np.int32),neuron_idx=np.array([2,5],np.int32)),audit={'synthetic_fixture':True})
|
||||
ci.generate_cs_requests=generate
|
||||
real_import=__import__
|
||||
def intercepted(name,*args,**kwargs):
|
||||
if name in ('conditioning_inputs','conditioning_preflight_inputs','evaluation_plan'):
|
||||
return {'conditioning_inputs':ci,'conditioning_preflight_inputs':i,'evaluation_plan':ep}[name]
|
||||
return real_import(name,*args,**kwargs)
|
||||
old_path=list(sys.path)
|
||||
try:
|
||||
with patch('builtins.__import__',side_effect=intercepted):
|
||||
result=S.run(regfile,S.A.digest(regfile),root/'runs/generated')
|
||||
self.assertEqual(len(calls),2);self.assertNotEqual(calls[0]['seed'],calls[1]['seed'])
|
||||
self.assertEqual(result['uniform_draws'],4800);self.assertFalse(result['brain_executed'])
|
||||
self.assertFalse(result['reuse_executed_here']);self.assertFalse(result['US_added'])
|
||||
self.assertEqual(set(result['files_sha256']),{'A-requests.npz','A-sampler.json','B-requests.npz','B-sampler.json'})
|
||||
with patch('builtins.__import__',side_effect=intercepted):
|
||||
with self.assertRaisesRegex(ValueError,'Exclusive new sampler'):S.run(regfile,S.A.digest(regfile),root/'runs/generated')
|
||||
return result
|
||||
finally:sys.path[:]=old_path
|
||||
|
||||
def test_only_two_fixed_batches_and_honest_scope(self):self.run_fixture()
|
||||
|
||||
def test_wrong_full_semantic_seed_rejected(self):
|
||||
with self.assertRaisesRegex(ValueError,'Evaluation semantic stream differs'):self.run_fixture(mutate_seed=True)
|
||||
|
||||
|
||||
if __name__=='__main__':unittest.main()
|
||||
@@ -0,0 +1,213 @@
|
||||
"""Small synthetic filesystem receipts; these are NOT real cost measurements."""
|
||||
from copy import deepcopy
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
import tempfile
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
import numpy as np
|
||||
import boundary_plan as P
|
||||
import budget_report as R
|
||||
|
||||
|
||||
class BudgetReportTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.tmp=tempfile.TemporaryDirectory();self.addCleanup(self.tmp.cleanup)
|
||||
self.root=Path(self.tmp.name);self.exp=self.root/'phase4-fixture';self.model=self.root/'model'
|
||||
for name in ('audit','receipts','jobs','logs','runs','updates','authorities','cases','protocol','extension-build'):
|
||||
(self.exp/name).mkdir(parents=True,exist_ok=True)
|
||||
self.model.mkdir();self.worker=self.model/'isolated_execution.py';self.ap=self.model/'ap_worker.py'
|
||||
for path in (self.worker,self.ap,self.model/'runtime_light.py',self.model/'runtime_continuation.py',self.model/'conditioning_epoch.py'):
|
||||
path.write_text('# CPU fixture '+path.name,encoding='utf-8')
|
||||
self.patch('EXP',self.exp);self.patch('MODEL',self.model);self.patch('AP_WORKER',self.ap)
|
||||
p=patch.object(R.F.W,'AP_SHA',R.A.digest(self.ap));p.start();self.addCleanup(p.stop)
|
||||
self.plan=P.build_plan();self.calls={c['call_id']:c for c in self.plan['calls']}
|
||||
self.zero=self.exp/'protocol/zero.npz';R.F.save_npz(self.zero,dict(delta=np.array([0.],np.float32)))
|
||||
self.reg=dict(plan=self.plan,source_sha256={str(self.worker):R.A.digest(self.worker)},
|
||||
initial_overlay=dict(overlay_file=str(self.zero),overlay_manifest=str(self.zero)),
|
||||
input_sha256={},prepared_file_sha256={})
|
||||
R.F.save(self.exp/'protocol/preregistered.json',self.reg);self.regsha=R.A.digest(self.exp/'protocol/preregistered.json')
|
||||
p=patch.object(R.F,'registration',side_effect=self.registration);p.start();self.addCleanup(p.stop)
|
||||
self.specs={};self.processes={};self.cycle_times={}
|
||||
self.put(self.exp/'extension-build/kernel.bin','actual-fixture-cache')
|
||||
for index,call in enumerate(self.plan['calls']):
|
||||
name=call['call_id'];start=(index+1)*100.;self.cycle_times[name]=(start,start+40.)
|
||||
if call['runner'] in ('runtime_light','fresh_probe'):
|
||||
case=self.exp/'cases'/name;case.mkdir()
|
||||
spec=dict(steps=call['steps'],dt_ms=.1,model=dict(frozen_fixture=True),apl=dict(gain=.01),
|
||||
precision='float64',apl_precision='float32',apl_delay_steps=18,
|
||||
graph_dir='pinned-fullgraph-fixture',apl_bundle_dir='pinned-APL-fixture')
|
||||
R.F.save(case/'spec.json',spec)
|
||||
R.F.save_npz(case/'requests.npz',dict(tick=np.array([5],np.int32),neuron_idx=np.array([20],np.int32)))
|
||||
self.specs[name]=case
|
||||
self._epoch(R.TRAIN);self._epoch('mechanical--fresh-parent')
|
||||
for arm in ('D1','D0','frozen'):self._process('AP-'+arm+'--cpu-verify','validate_cpu',10.)
|
||||
for call in self.plan['calls']:
|
||||
name=call['call_id'];start=self.cycle_times[name][0]
|
||||
kind={'runtime_light':'brain','fresh_probe':'brain','runtime_continuation':'unchanged',
|
||||
'updated_continuation':'updated','boundary_oracle':'oracle'}[call['runner']]
|
||||
self._process(name,kind,start+1)
|
||||
if name in (R.TRAIN,'mechanical--fresh-parent'):
|
||||
self._process(name+'--original-E','update',start+11,base=name)
|
||||
self._process(name+'--cpu-verify','validate_cpu',start+21,base=name)
|
||||
self._process('evaluation-inputs','sample',self.cycle_times[R.TRAIN][1]+10)
|
||||
build=R.F.tree(self.exp/'extension-build')
|
||||
for call in self.plan['calls']:
|
||||
name=call['call_id'];start,end=self.cycle_times[name]
|
||||
rows=[self.processes[event] for _,event in R.SELECTED[name]] if name in R.SELECTED else []
|
||||
inventory=R._cycle_files(name,rows,R.Evidence()) if rows else {}
|
||||
value=dict(call=call,complete=True,start_monotonic=start,end_monotonic=end,wall_seconds=end-start,
|
||||
output_inventory=inventory,output_bytes=sum(v['bytes'] for v in inventory.values()),
|
||||
mutable_build_inventory_before=build,mutable_build_inventory_after=build,
|
||||
mutable_build_bytes_before=sum(v['bytes'] for v in build.values()),
|
||||
mutable_build_bytes_after=sum(v['bytes'] for v in build.values()),
|
||||
source_registration_sha256=self.regsha,learning_pass_claimed=False)
|
||||
R.F.save(self.exp/'receipts'/f'{name}.cycle.json',value)
|
||||
R.F.save(self.exp/'audit/execution-attempt.json',dict(registration_sha256=self.regsha,monotonic_origin=1.))
|
||||
R.F.save(self.exp/'audit/execution-complete.json',dict(complete=True,registration_sha256=self.regsha,
|
||||
scientific_learning_pass_claimed=False,completed_calls=[c['call_id'] for c in self.plan['calls']],
|
||||
processes={name:str(self.exp/'receipts'/f'{name}.process.json') for name in self.processes}))
|
||||
|
||||
def patch(self,key,value):
|
||||
p=patch.object(R.F,key,value);p.start();self.addCleanup(p.stop)
|
||||
|
||||
def registration(self,sha):
|
||||
R.require(sha==R.A.digest(self.exp/'protocol/preregistered.json'),'Registration differs')
|
||||
return self.reg
|
||||
|
||||
def put(self,path,text):
|
||||
Path(path).write_text(text,encoding='utf-8')
|
||||
|
||||
def rewrite(self,path,mutate):
|
||||
value=R.A.read(path);mutate(value)
|
||||
self.put(path,json.dumps(value,sort_keys=True,allow_nan=False))
|
||||
|
||||
def _epoch(self,name):
|
||||
R.F.save(self.exp/'authorities'/f'{name}.epoch.json',dict(checkpoint_dir=str(self.exp/'runs'/name),
|
||||
command=dict(steps=1200,compartment="y5B'2a",us_tick=900 if name==R.TRAIN else 1199,
|
||||
d_command=1.,frozen=False,trace_backend='torch')))
|
||||
|
||||
def _process(self,name,kind,start,base=None):
|
||||
ap=kind in ('brain','update');script=self.ap if ap else self.worker
|
||||
output=self.exp/('updates' if kind=='update' else 'runs')/(base if kind=='update' else name);output.mkdir()
|
||||
sources={role:dict(path=str(self.model/(role+'.py')),sha256=R.A.digest(self.model/(role+'.py')))
|
||||
for role in (('runtime_light','runtime_continuation') if kind=='brain' else ('conditioning_epoch',))} if ap else {}
|
||||
job=dict(job_id=name,kind=kind,registration_sha256=self.regsha,worker_sha256=R.A.digest(script),
|
||||
receipt_file=str(self.exp/'receipts'/f'{name}.worker.json'),output_dir=str(output),
|
||||
input_sha256={str(self.exp/'protocol/preregistered.json'):self.regsha},sources=sources,source_sha256={})
|
||||
result={};environment=dict(gpu_uuid='FIXTURE',python_version='fixture',torch_version='fixture')
|
||||
if kind=='brain':
|
||||
job.update(case_dir=str(self.specs[name]),diagnostic_mode=self.calls[name]['diagnostic_mode'],overlay_file=str(self.zero))
|
||||
summary=dict(steps=1200,completed_ticks=1200,explicit_steps_executed=1200,max_steps=1200,nodes=R.B.N,edges=R.B.E,
|
||||
diagnostic_mode=job['diagnostic_mode'],entire_neural_trial_executed=True,within_trial_weight_updates=False,
|
||||
precision='float64',apl_precision='float32')
|
||||
R.F.save(output/'summary.json',summary);result['complete_fresh_trial']=True
|
||||
elif kind=='sample':
|
||||
for cue in ('A','B'):
|
||||
R.F.save_npz(output/f'{cue}-requests.npz',dict(tick=np.array([5],np.int32),neuron_idx=np.array([20],np.int32)))
|
||||
else:R.F.save(output/'fixture.json',dict(complete=True))
|
||||
if base:
|
||||
job.update(authority_file=str(self.exp/'authorities'/f'{base}.epoch.json'))
|
||||
if kind=='validate_cpu':job['update_dir']=str(self.exp/'updates'/base)
|
||||
jobpath=self.exp/'jobs'/f'{name}.json';R.F.save(jobpath,job);jobsha=R.A.digest(jobpath)
|
||||
expected={**job['input_sha256'],str(jobpath):jobsha,str(script):job['worker_sha256']}
|
||||
if ap:expected.update({v['path']:v['sha256'] for v in sources.values()})
|
||||
else:expected[str(self.ap)]=R.F.W.AP_SHA
|
||||
logs={}
|
||||
for side in ('stdout','stderr'):
|
||||
path=self.exp/'logs'/f'{name}.{side}.log';self.put(path,'');logs[side+'_sha256']=R.A.digest(path)
|
||||
attempt=self.exp/'receipts'/f'{name}.worker.json.attempt.json';R.F.save(attempt,dict(fixture=True))
|
||||
inventory=R.F.tree(output);hashes={k:v['sha256'] for k,v in inventory.items()}
|
||||
worker=dict(schema='phase4ap-isolated-worker-receipt-v1' if ap else 'conditioning-isolated-execution-receipt-v1',
|
||||
complete=True,job_id=name,kind=kind,registration_sha256=self.regsha,worker_sha256=job['worker_sha256'],
|
||||
job_sha256=jobsha,attempt_sha256=R.A.digest(attempt),output_dir=str(output),output_files_sha256=hashes,
|
||||
environment=environment,result=result,wall_seconds=2.)
|
||||
worker['verified_input_sha256' if ap else 'input_sha256']=expected
|
||||
workerpath=Path(job['receipt_file']);R.F.save(workerpath,worker)
|
||||
command=['fixture-python','-B',str(script)]+([kind] if ap else [])+['--job',str(jobpath),'--job-sha256',jobsha]
|
||||
process=dict(schema='conditioning-execution-process-v1',complete=True,name=name,kind=kind,
|
||||
registration_sha256=self.regsha,exit_code=0,timed_out=False,job_sha256=jobsha,argv=command,
|
||||
worker_receipt_sha256=R.A.digest(workerpath),spawn_monotonic=start,exit_monotonic=start+4.,
|
||||
validation_end_monotonic=start+5.,child_wall_seconds=4.,end_to_end_seconds=5.,validation_wall_seconds=1.,
|
||||
output_bytes=sum(v['bytes'] for v in inventory.values()),
|
||||
output_inventory_sha256=hashlib.sha256(json.dumps(hashes,sort_keys=True).encode()).hexdigest(),**logs)
|
||||
processpath=self.exp/'receipts'/f'{name}.process.json';R.F.save(processpath,process)
|
||||
self.processes[name]=dict(process=process,job=job,worker=worker,output_inventory=inventory,
|
||||
binding=dict(receipt_id=str(processpath),sha256=R.A.digest(processpath)))
|
||||
|
||||
def report(self,save=False):return R.report(self.regsha,save_report=save)
|
||||
|
||||
def test_actual_cycles_tail_complete_bytes_and_no_forecast_without_future_policy(self):
|
||||
value=self.report()
|
||||
self.assertEqual(value['status'],'INSUFFICIENT-MEASUREMENTS')
|
||||
self.assertEqual(value['policy_status'],'FUTURE-POLICY-NOT-REGISTERED')
|
||||
self.assertEqual(value['registration_sha256'],self.regsha)
|
||||
self.assertEqual(value['inventory']['brain_calls'],33920)
|
||||
self.assertEqual({r['cycle_id'] for r in value['measurements']},{R.TRAIN,R.PROBE})
|
||||
for name in (R.TRAIN,R.PROBE):
|
||||
account=value['accounting'][name]
|
||||
self.assertEqual((account['recorded_cycle_seconds'],account['tail_upper_bound_seconds'],
|
||||
account['conservative_complete_cycle_seconds']),(40.,60.,100.))
|
||||
self.assertEqual(account['total_conservative_bytes'],account['created_bytes']+
|
||||
account['cycle_receipt_bytes']+account['repeated_full_cache_bytes'])
|
||||
self.assertGreater(account['cycle_receipt_bytes'],0)
|
||||
self.assertIsNone(value['estimated_wall_seconds']);self.assertIsNone(value['estimated_output_bytes'])
|
||||
self.assertIsNone(value['strict_projection']['estimated_wall_seconds'])
|
||||
self.assertFalse(value['learning_pass_claimed']);self.assertFalse(value['execution_authorized'])
|
||||
|
||||
def test_saved_report_reproduces_exactly_and_is_exclusive(self):
|
||||
first=self.report(True);second=self.report(False)
|
||||
self.assertEqual(R._canonical(first),R._canonical(second))
|
||||
self.assertEqual(R._canonical(first),R._canonical(R.A.read(self.exp/'audit/budget-report.json')))
|
||||
with self.assertRaisesRegex(ValueError,'never overwrite'):self.report(True)
|
||||
self.assertNotIn('generated_at',first);self.assertNotIn('free_bytes',first)
|
||||
|
||||
def test_worker_byte_tampering_and_wrong_registration_rejected(self):
|
||||
path=self.exp/'receipts'/f'{R.TRAIN}.worker.json'
|
||||
self.rewrite(path,lambda r:r.update(wall_seconds=.01))
|
||||
with self.assertRaisesRegex(ValueError,'Evidence bytes changed'):self.report()
|
||||
with self.assertRaises(ValueError):R.report('f'*64,save_report=False)
|
||||
|
||||
def test_unsuccessful_parent_process_cannot_be_reclassified_by_worker(self):
|
||||
path=self.exp/'receipts'/f'{R.TRAIN}.process.json'
|
||||
self.rewrite(path,lambda r:r.update(exit_code=1))
|
||||
with self.assertRaisesRegex(ValueError,'Unsuccessful'):self.report()
|
||||
|
||||
def test_cycle_inventory_omission_not_mistaken_for_full_output_bytes(self):
|
||||
path=self.exp/'receipts'/f'{R.TRAIN}.cycle.json'
|
||||
def omit(row):
|
||||
key=next(iter(row['output_inventory']));del row['output_inventory'][key]
|
||||
row['output_bytes']=sum(v['bytes'] for v in row['output_inventory'].values())
|
||||
self.rewrite(path,omit)
|
||||
with self.assertRaisesRegex(ValueError,'complete fixed-branch scope'):self.report()
|
||||
|
||||
def test_missing_cycle_evidence_returns_insufficient_without_inventing_measurement(self):
|
||||
(self.exp/'receipts'/f'{R.TRAIN}.cycle.json').unlink()
|
||||
value=self.report()
|
||||
self.assertEqual(value['status'],'INSUFFICIENT-MEASUREMENTS')
|
||||
self.assertEqual(value['measurements'],[])
|
||||
self.assertTrue(any('evidence missing' in item for item in value['missing']))
|
||||
self.assertIsNone(value['estimated_output_bytes'])
|
||||
|
||||
def test_inconsistent_adjacent_clock_cannot_supply_tail_upper_bound(self):
|
||||
path=self.exp/'receipts'/f'{R.PROBE}.cycle.json'
|
||||
self.rewrite(path,lambda r:r.update(start_monotonic=self.cycle_times[R.TRAIN][1]-1))
|
||||
with self.assertRaisesRegex(ValueError,'adjacent-cycle tail'):self.report()
|
||||
|
||||
def test_mutable_cache_final_bytes_must_match_observed_final_inventory(self):
|
||||
self.put(self.exp/'extension-build/kernel.bin','changed-after-observation')
|
||||
with self.assertRaisesRegex(ValueError,'mutable cache inventory changed'):self.report()
|
||||
|
||||
def test_reference_or_continuation_not_admitted_as_fresh_performance(self):
|
||||
real=R._parent_process
|
||||
def different(name,*args):
|
||||
row=real(name,*args)
|
||||
if name==R.PROBE:row=deepcopy(row);row['job']['diagnostic_mode']='reference'
|
||||
return row
|
||||
with patch.object(R,'_parent_process',side_effect=different):
|
||||
with self.assertRaisesRegex(ValueError,'fresh light'):self.report()
|
||||
|
||||
|
||||
if __name__=='__main__':unittest.main()
|
||||
@@ -0,0 +1,103 @@
|
||||
"""Pure authority construction tests; synthetic files, no graph or GPU claims."""
|
||||
import copy
|
||||
import json
|
||||
from pathlib import Path
|
||||
import tempfile
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
import execution_authority as A
|
||||
|
||||
|
||||
class AuthorityTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.tmp=tempfile.TemporaryDirectory();self.root=Path(self.tmp.name).resolve()
|
||||
self.case=self.root/'case';self.parent=self.root/'parent';self.update=self.root/'update'
|
||||
for p in (self.case,self.parent,self.update):p.mkdir()
|
||||
self.write(self.parent/'checkpoint-manifest.json',{'fixture':True})
|
||||
self.write(self.parent/'summary.json',{'steps':1200,'effective_weights_raw_sha256':'a'*64,'diagnostic_mode':'reference'})
|
||||
self.write(self.case/'spec.json',{'steps':1000,'global_tick_offset':1200,
|
||||
'parent_checkpoint_manifest_sha256':A.digest(self.parent/'checkpoint-manifest.json')})
|
||||
(self.case/'requests.npz').write_bytes(b'synthetic-file-not-a-real-npz')
|
||||
(self.parent/'state.npz').write_bytes(b'synthetic-state-not-a-real-npz')
|
||||
self.before=dict(overlay_file=str(self.root/'before.npz'),overlay_manifest=str(self.root/'before.json'))
|
||||
self.after=dict(overlay_file=str(self.root/'after.npz'),overlay_manifest=str(self.root/'after.json'))
|
||||
for p in (*self.before.values(),*self.after.values()):Path(p).write_bytes(b'fixture')
|
||||
self.epoch=self.root/'epoch.json';self.cpu=self.root/'cpu.json'
|
||||
self.write(self.epoch,{});self.write(self.cpu,{})
|
||||
for n in ('chain-receipt.json','update-receipt.json','delta-after.npz','overlay-manifest.json'):
|
||||
(self.update/n).write_bytes(b'fixture')
|
||||
|
||||
def tearDown(self):self.tmp.cleanup()
|
||||
|
||||
def write(self,path,value):path.write_text(json.dumps(value),encoding='utf-8')
|
||||
|
||||
def make(self,**changes):
|
||||
kw=dict(boundary_id='fixture',registration_sha256='c'*64,case=self.case,parent=self.parent,
|
||||
transition='epoch_update',input_policy='empty_idle',mode='light',before_overlay=self.before,
|
||||
after_overlay=self.after,source_files={'fixture':A.pin(self.cpu)},frozen_inputs={str(self.epoch):A.digest(self.epoch)},
|
||||
epoch=self.epoch,update_dir=self.update,cpu_receipt=self.cpu)
|
||||
kw.update(changes)
|
||||
# Hash computation is stubbed only here: no effective-weight verification claim.
|
||||
with patch.object(A,'effective_hash',side_effect=['a'*64,'b'*64] if kw['transition']=='epoch_update' else ['a'*64]*2):
|
||||
return A.boundary_authority(**kw)
|
||||
|
||||
def test_exact_boundary_fields_and_live_payload_pins(self):
|
||||
value=self.make()
|
||||
self.assertEqual(value['global_tick_offset'],1200)
|
||||
self.assertEqual(value['parent']['checkpoint_manifest_sha256'],A.digest(self.parent/'checkpoint-manifest.json'))
|
||||
self.assertEqual(value['update']['files']['delta-after.npz'],A.pin(self.update/'delta-after.npz'))
|
||||
self.assertEqual(value['expected_effective_weight_after_sha256'],'b'*64)
|
||||
|
||||
def test_changed_clock_or_parent_rejected(self):
|
||||
original=A.read(self.case/'spec.json')
|
||||
for key,value in (('global_tick_offset',1199),('parent_checkpoint_manifest_sha256','0'*64)):
|
||||
spec={**original,key:value};self.write(self.case/'spec.json',spec)
|
||||
with self.subTest(key=key),self.assertRaises(ValueError):self.make()
|
||||
|
||||
def test_later_parent_uses_absolute_next_tick(self):
|
||||
summary=A.read(self.parent/'summary.json');summary['global_next_tick']=11200
|
||||
self.write(self.parent/'summary.json',summary)
|
||||
spec=A.read(self.case/'spec.json');spec['global_tick_offset']=11200;self.write(self.case/'spec.json',spec)
|
||||
value=self.make(transition='idle',epoch=None,update_dir=None,cpu_receipt=None)
|
||||
self.assertEqual(value['global_tick_offset'],11200);self.assertIsNone(value['update'])
|
||||
|
||||
def test_epoch_update_requires_all_evidence(self):
|
||||
for name in ('epoch','update_dir','cpu_receipt'):
|
||||
with self.subTest(name=name),self.assertRaises(ValueError):self.make(**{name:None})
|
||||
|
||||
def test_idle_cannot_carry_new_update(self):
|
||||
with self.assertRaisesRegex(ValueError,'Idle cannot'):self.make(transition='idle')
|
||||
|
||||
def test_boundary_copies_descriptors_not_aliases(self):
|
||||
sources={'role':A.pin(self.cpu)};frozen={str(self.epoch):A.digest(self.epoch)}
|
||||
value=self.make(source_files=sources,frozen_inputs=frozen)
|
||||
sources['role']['sha256']='0'*64;frozen.clear()
|
||||
self.assertNotEqual(value['source_files'],sources);self.assertTrue(value['frozen_inputs'])
|
||||
|
||||
def test_complete_direct_closure_and_conflicting_pin(self):
|
||||
value=self.make();pins=A.files_from_authority(value)
|
||||
for p in (self.epoch,self.cpu,self.case/'requests.npz',self.parent/'checkpoint-manifest.json',self.update/'delta-after.npz'):
|
||||
self.assertEqual(pins[str(p)],A.digest(p))
|
||||
value['frozen_inputs'][str(self.cpu)]='0'*64
|
||||
with self.assertRaisesRegex(ValueError,'Conflicting'):A.files_from_authority(value)
|
||||
|
||||
def test_epoch_template_is_not_modified(self):
|
||||
spec=A.read(self.case/'spec.json');spec['steps']=1200;self.write(self.case/'spec.json',spec)
|
||||
template=dict(schema='phase4an-epoch-postprocess-authority-v1',files={'old':{'path':'literal','sha256':'1'*64}},
|
||||
frozen_inputs={'literal':'1'*64})
|
||||
original=copy.deepcopy(template)
|
||||
result=A.epoch_authority(template,case=self.case,checkpoint=self.parent,overlay=self.before,
|
||||
epoch_id='mechanical',us_tick=1199)
|
||||
self.assertEqual(template,original);self.assertEqual(result['command']['us_tick'],1199)
|
||||
self.assertEqual(result['files']['state'],A.pin(self.parent/'state.npz'))
|
||||
with self.assertRaises(ValueError):A.epoch_authority(template,case=self.case,checkpoint=self.parent,
|
||||
overlay=self.before,epoch_id='bad',us_tick=1200)
|
||||
|
||||
def test_duplicate_or_nonfinite_JSON_rejected(self):
|
||||
for data in ('{"a":1,"a":2}','{"a":NaN}'):
|
||||
self.cpu.write_text(data)
|
||||
with self.assertRaises(ValueError):A.read(self.cpu)
|
||||
|
||||
|
||||
if __name__=='__main__':unittest.main()
|
||||
@@ -0,0 +1,142 @@
|
||||
"""Synthetic CPU-only budget contract tests, not measured performance evidence."""
|
||||
from copy import deepcopy
|
||||
import unittest
|
||||
|
||||
import execution_budget as B
|
||||
|
||||
|
||||
CONTEXT = 'a'*64
|
||||
|
||||
|
||||
class BudgetTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.auth = {}
|
||||
self.reserves = {role:dict(wall_seconds=1.,output_bytes=2,basis='explicit fixture allowance')
|
||||
for role in B.RESERVE_ROLES}
|
||||
self.reserves['cycle_multiplier'] = 1.25
|
||||
|
||||
def bind(self, name):
|
||||
self.auth[name] = 'b'*64
|
||||
return dict(receipt_id=name,sha256='b'*64)
|
||||
|
||||
def cycle(self, name, kind='training', mode='light', steps=1200):
|
||||
events = []
|
||||
roles = ['brain','original_E','cpu_validator'] if kind == 'training' else ['brain']
|
||||
for i,role in enumerate(roles):
|
||||
events.append(dict(event_id=name+'-'+role,role=role,receipt_kind='parent-process',
|
||||
receipt=self.bind(name+'-'+role),spawn_s=1.+i*4,exit_s=3.+i*4,validated_s=4.+i*4,
|
||||
exit_code=0,core_seconds=.5,runtime_seconds=1.,child_wall_seconds=2.))
|
||||
return dict(schema=B.SCHEMA,cycle_id=name,kind=kind,diagnostic_mode=mode,steps=steps,
|
||||
neurons=B.N,edges=B.E,dt_ms=.1,context_sha256=CONTEXT,clock_id='parent-clock-1',
|
||||
started_s=0.,validated_s=len(roles)*4.+1,authority=self.bind(name+'-cycle'),events=events,
|
||||
outputs=dict(inventory=self.bind(name+'-inventory'),scope=B.OUTPUT_SCOPE,complete=True,total_bytes=1000),complete=True)
|
||||
|
||||
def estimate(self, rows, **kwargs):
|
||||
return B.estimate_normal_suite(rows,authenticated_receipts=self.auth,target_context_sha256=CONTEXT,
|
||||
reserves=self.reserves,**kwargs)
|
||||
|
||||
def test_full_training_probe_cycles_use_only_end_to_end_and_complete_bytes(self):
|
||||
train,probe = self.cycle('train'),self.cycle('probe','probe')
|
||||
report = self.estimate([train,probe])
|
||||
self.assertEqual(report['status'],'ESTIMATED-NOT-AUTHORIZED')
|
||||
self.assertEqual(report['inventory']['brain_calls'],33920)
|
||||
self.assertEqual(report['inventory']['biological_seconds'],4070.4)
|
||||
self.assertEqual(report['estimated_wall_seconds'],int(1.25*(30000*13+3920*5)+5))
|
||||
self.assertEqual(report['estimated_output_bytes'],int(1.25*33920*1000+10))
|
||||
self.assertEqual(report['measured_cycles'][0]['timing'],dict(core_seconds=1.5,runtime_seconds=3.,
|
||||
child_wall_seconds=6.,end_to_end_seconds=13.))
|
||||
for field in ('execution_authorized','scientific_learning_claimed','external_identity_verified_here'):
|
||||
self.assertFalse(report[field])
|
||||
|
||||
def test_missing_either_cycle_returns_symbolic_not_pseudo_precise_total(self):
|
||||
for rows in ([],[self.cycle('only-train')],[self.cycle('only-probe','probe')]):
|
||||
report = self.estimate(rows)
|
||||
self.assertEqual(report['status'],'INSUFFICIENT-MEASUREMENTS')
|
||||
self.assertIsNone(report['estimated_wall_seconds'])
|
||||
self.assertIsNone(report['estimated_output_bytes'])
|
||||
self.assertTrue(report['missing'])
|
||||
self.assertIn('30000',report['symbolic_wall'])
|
||||
|
||||
def test_reference_idle_short_wrong_context_are_reported_but_not_training_samples(self):
|
||||
rows = [self.cycle('ref',mode='reference'),self.cycle('idle','state_only_idle',steps=10000),
|
||||
self.cycle('short',steps=1000),self.cycle('other')]
|
||||
rows[-1]['context_sha256'] = 'c'*64
|
||||
report = self.estimate(rows+[self.cycle('probe','probe')])
|
||||
self.assertEqual(report['status'],'INSUFFICIENT-MEASUREMENTS')
|
||||
self.assertEqual(report['eligible_cycle_ids']['training'],[])
|
||||
self.assertEqual(len(report['measured_cycles']),5)
|
||||
|
||||
def test_actual_parent_event_order_receipts_and_complete_output_required(self):
|
||||
mutations = [lambda r:r['events'].pop(),lambda r:r['events'][0].update(receipt_kind='AP-worker-slot'),
|
||||
lambda r:r['events'][1].update(spawn_s=0.),lambda r:r['events'][0].update(exit_code=1),
|
||||
lambda r:r['events'][0]['receipt'].update(sha256='f'*64),
|
||||
lambda r:r['outputs'].update(complete=False),lambda r:r['outputs'].update(scope='state-only'),
|
||||
lambda r:r['outputs'].update(total_bytes=True),lambda r:r.update(neurons=16),
|
||||
lambda r:r['events'][0].update(child_wall_seconds=1.),lambda r:r.update(complete=1),
|
||||
lambda r:r['events'][0].update(runtime_seconds=3.),lambda r:r.update(validated_s=float('nan'))]
|
||||
for i,mutate in enumerate(mutations):
|
||||
row = self.cycle('mutate'+str(i))
|
||||
mutate(row)
|
||||
with self.assertRaises(ValueError):
|
||||
self.estimate([row])
|
||||
with self.assertRaises(ValueError):
|
||||
self.estimate([dict(wall_seconds=10,slot='D1')])
|
||||
|
||||
def test_reserves_have_no_implicit_defaults_and_caps_stop_without_inventory_change(self):
|
||||
rows = [self.cycle('train'),self.cycle('probe','probe')]
|
||||
report = self.estimate(rows,limits=dict(wall_seconds=1,output_bytes=1))
|
||||
self.assertEqual(report['status'],'STOP-BUDGET-EXCEEDED')
|
||||
self.assertFalse(report['caps_pass'])
|
||||
self.assertEqual(report['inventory'],B.INVENTORY)
|
||||
original = deepcopy(self.reserves)
|
||||
for role in B.RESERVE_ROLES | {'cycle_multiplier'}:
|
||||
self.reserves = deepcopy(original)
|
||||
del self.reserves[role]
|
||||
with self.assertRaises(ValueError):
|
||||
self.estimate(rows)
|
||||
self.reserves = deepcopy(original)
|
||||
self.reserves['cycle_multiplier'] = .99
|
||||
with self.assertRaises(ValueError):
|
||||
self.estimate(rows)
|
||||
|
||||
def test_maxima_not_fitted_or_pooled_with_reference_and_no_mutation(self):
|
||||
slow = self.cycle('slow')
|
||||
slow['validated_s'] = 25.
|
||||
slow['outputs']['total_bytes'] = 2000
|
||||
ref = self.cycle('ref',mode='reference')
|
||||
ref['validated_s'] = 10000.
|
||||
rows = [self.cycle('fast'),slow,ref,self.cycle('probe','probe')]
|
||||
saved = deepcopy(rows)
|
||||
report = self.estimate(rows)
|
||||
self.assertEqual(report['estimated_wall_seconds'],int(1.25*(30000*25+3920*5)+5))
|
||||
self.assertEqual(report['estimated_output_bytes'],int(1.25*(30000*2000+3920*1000)+10))
|
||||
self.assertEqual(rows,saved)
|
||||
|
||||
def test_missing_core_runtime_are_unknown_not_required_for_end_to_end(self):
|
||||
train,probe = self.cycle('train'),self.cycle('probe','probe')
|
||||
for event in train['events']:
|
||||
event.update(core_seconds=None,runtime_seconds=None)
|
||||
report = self.estimate([train,probe])
|
||||
self.assertEqual(report['status'],'ESTIMATED-NOT-AUTHORIZED')
|
||||
self.assertIsNone(report['measured_cycles'][0]['timing']['core_seconds'])
|
||||
self.assertIsNone(report['measured_cycles'][0]['timing']['runtime_seconds'])
|
||||
self.assertEqual(report['measured_cycles'][0]['timing']['end_to_end_seconds'],13.)
|
||||
|
||||
def test_duplicate_events_and_probe_updates_rejected(self):
|
||||
train = self.cycle('train')
|
||||
duplicate = deepcopy(train)
|
||||
duplicate['cycle_id'] = 'forged-second-cycle'
|
||||
with self.assertRaises(ValueError):
|
||||
self.estimate([train,duplicate])
|
||||
for event in duplicate['events']:
|
||||
event['event_id'] += '-renamed'
|
||||
with self.assertRaises(ValueError):
|
||||
self.estimate([train,duplicate])
|
||||
probe = self.cycle('probe','probe')
|
||||
probe['events'].append(deepcopy(train['events'][1]))
|
||||
with self.assertRaises(ValueError):
|
||||
self.estimate([probe])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -0,0 +1,333 @@
|
||||
"""CPU-only workflow mocks: real local receipts/files, never GPU/remote calls."""
|
||||
from copy import deepcopy
|
||||
import importlib.util
|
||||
import json
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
from types import SimpleNamespace
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
import numpy as np
|
||||
import boundary_plan as P
|
||||
import execution_workflow as F
|
||||
|
||||
|
||||
class WorkflowTests(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
path=Path(__file__).resolve().parent.parent/'conditioning-interface-v2/isolated_workers.py'
|
||||
spec=importlib.util.spec_from_file_location('workflow_test_frozen_AP_worker',path)
|
||||
cls.ap=importlib.util.module_from_spec(spec);spec.loader.exec_module(cls.ap)
|
||||
|
||||
def setUp(self):
|
||||
self.tmp = tempfile.TemporaryDirectory()
|
||||
self.addCleanup(self.tmp.cleanup)
|
||||
self.base = Path(self.tmp.name)
|
||||
self.exp,self.model,self.lab = (self.base/n for n in ('phase4-fixture','model','lab'))
|
||||
for name in ('protocol/case-templates','inputs/static','cases','runs','updates','jobs','authorities',
|
||||
'receipts','logs','audit','extension-build'):
|
||||
(self.exp/name).mkdir(parents=True,exist_ok=True)
|
||||
self.model.mkdir(); self.lab.mkdir()
|
||||
self.ap_worker = self.base/'ap_worker.py'
|
||||
self.put(self.ap_worker,'# fixture AP worker')
|
||||
sources = {}
|
||||
for name in set().union(*F.W.SOURCES.values()) | {'isolated_execution.py'}:
|
||||
path = self.model/name; self.put(path,'# fixture source '+name); sources[str(path)]=F.digest(path)
|
||||
for name in ('runtime_light','runtime_continuation','conditioning_update','eligibility_bridge',
|
||||
'phase4j','am_overlay','conditioning_epoch','conditioning_preflight_compare','engineering_compare'):
|
||||
self.put(self.lab/(name+'.py'),'# fixture '+name)
|
||||
self.patches = [patch.object(F,'EXP',self.exp),patch.object(F,'MODEL',self.model),
|
||||
patch.object(F,'LAB',self.lab),patch.object(F,'AP_WORKER',self.ap_worker)]
|
||||
for item in self.patches:
|
||||
item.start(); self.addCleanup(item.stop)
|
||||
self.plan=P.build_plan(); self.calls={c['call_id']:c for c in self.plan['calls']}
|
||||
self.requests=dict(tick=np.array([3,900],np.int32),neuron_idx=np.array([12,15],np.int32))
|
||||
F.save_npz(self.exp/'inputs/static/mechanical-requests.npz',self.requests)
|
||||
self.initial=self.overlay('zero')
|
||||
parents={}
|
||||
for arm,descriptor in self.plan['imported_parents'].items():
|
||||
directory=self.base/('AP-'+arm); directory.mkdir()
|
||||
self.checkpoint(directory,1200,'reference')
|
||||
update=self.base/('AP-'+arm+'-update'); self.update_files(update)
|
||||
before=self.overlay('before-'+arm)
|
||||
case=self.base/('AP-'+arm+'-case');case.mkdir()
|
||||
F.save(case/'spec.json',dict(steps=1200));F.save_npz(case/'requests.npz',self.requests)
|
||||
epoch=dict(schema='phase4an-epoch-postprocess-authority-v1',checkpoint_dir=str(directory),
|
||||
checkpoint_manifest_sha256=F.digest(directory/'checkpoint-manifest.json'),
|
||||
files={'requests':F.A.pin(case/'requests.npz')},frozen_inputs={})
|
||||
for role in ('runtime_continuation','runtime_light','conditioning_update','eligibility_bridge','phase4j','am_overlay'):
|
||||
epoch['files'][role+'_source']=F.A.pin(self.lab/(role+'.py'))
|
||||
ep=self.base/('AP-'+arm+'.epoch.json');F.save(ep,epoch)
|
||||
parents[descriptor['role']]=dict(directory=str(directory),checkpoint_sha256=epoch['checkpoint_manifest_sha256'],
|
||||
epoch_authority=F.A.pin(ep),update_dir=str(update),before_overlay=before,
|
||||
after_overlay=dict(overlay_file=str(update/'delta-after.npz'),overlay_manifest=str(update/'overlay-manifest.json')))
|
||||
templates={}
|
||||
for call in self.plan['calls']:
|
||||
group=call['case_group']
|
||||
if group not in templates:
|
||||
path=self.exp/'protocol/case-templates'/f'{group}.json'
|
||||
F.save(path,dict(name=group,steps=call['steps'],max_steps=call['steps'],
|
||||
within_trial_weight_updates=call.get('within_trial_weight_updates',False)))
|
||||
templates[group]=str(path)
|
||||
self.reg=dict(plan=self.plan,parent_records=parents,initial_overlay=self.initial,case_templates=templates,
|
||||
source_sha256=sources,input_sha256={},prepared_file_sha256={},budget=dict(root=str(self.exp),
|
||||
output_cap_bytes=2**30,minimum_free_reserve_bytes=0,child_timeout_seconds=20,workflow_timeout_seconds=7200))
|
||||
F.save(self.exp/'protocol/preregistered.json',self.reg)
|
||||
self.w=F.Workflow.__new__(F.Workflow)
|
||||
self.w.sha=F.digest(self.exp/'protocol/preregistered.json');self.w.reg=self.reg
|
||||
self.w.parents=deepcopy(parents);self.w.jobs={};self.w.boundaries={};self.w.completed=[];self.w.cycles=[];self.w.sampler=None
|
||||
self.w.started=0.;self.w.deadline=10**12
|
||||
self.w.h=SimpleNamespace(GPU='fixture-gpu',COMFY_URLS=('fixture-queue',),
|
||||
SOURCE_PINS={n:F.digest(self.lab/(n+'.py')) for n in ('runtime_light','runtime_continuation','conditioning_epoch')})
|
||||
self.launched=[];self.boundary_args=[]
|
||||
|
||||
def put(self,path,text):
|
||||
path=Path(path);path.parent.mkdir(parents=True,exist_ok=True)
|
||||
path.write_text(text,encoding='utf-8')
|
||||
|
||||
def overlay(self,name):
|
||||
npz=self.base/(name+'.npz');meta=self.base/(name+'.json')
|
||||
F.save_npz(npz,dict(delta=np.array([0.],np.float32)));F.save(meta,dict(fixture=name))
|
||||
return dict(overlay_file=str(npz),overlay_manifest=str(meta))
|
||||
|
||||
def checkpoint(self,directory,steps,mode,offset=0):
|
||||
F.save(directory/'summary.json',dict(steps=steps,diagnostic_mode=mode,global_next_tick=offset+steps,
|
||||
effective_weights_raw_sha256='f'*64))
|
||||
F.save_npz(directory/'state.npz',dict(step=np.array([0],np.int32)))
|
||||
F.save(directory/'checkpoint-manifest.json',dict(fixture=True,steps=steps))
|
||||
|
||||
def update_files(self,directory):
|
||||
directory.mkdir()
|
||||
for name in ('chain-receipt.json','update-receipt.json','overlay-manifest.json'):
|
||||
F.save(directory/name,dict(fixture=True))
|
||||
F.save_npz(directory/'delta-after.npz',dict(delta=np.array([-.01],np.float32)))
|
||||
|
||||
def fake_boundary(self,**kw):
|
||||
self.boundary_args.append(deepcopy(kw))
|
||||
case=Path(kw['case']);parent=Path(kw['parent'])
|
||||
return dict(schema='conditioning-updated-boundary-v1',transition=kw['transition'],
|
||||
diagnostic_mode=kw['mode'],boundary_id=kw['boundary_id'],
|
||||
case=dict(spec=F.A.pin(case/'spec.json'),requests=F.A.pin(case/'requests.npz')),
|
||||
parent=dict(directory=str(parent),checkpoint_manifest_sha256=F.digest(parent/'checkpoint-manifest.json')),
|
||||
overlay_before={k:F.A.pin(v) for k,v in kw['before_overlay'].items()},
|
||||
overlay_after={k:F.A.pin(v) for k,v in kw['after_overlay'].items()},
|
||||
source_files=kw['source_files'],frozen_inputs={})
|
||||
|
||||
def fake_launch(self,name,job,*,ap=False):
|
||||
self.launched.append((name,deepcopy(job),ap));output=Path(job['output_dir'])
|
||||
kind=job['kind'];result={}
|
||||
if kind=='update':self.update_files(output)
|
||||
else:
|
||||
output.mkdir()
|
||||
if kind=='sample':
|
||||
for cue,node in (('A',20),('B',30)):
|
||||
F.save_npz(output/f'{cue}-requests.npz',dict(tick=np.array([5],np.int32),neuron_idx=np.array([node],np.int32)))
|
||||
elif kind=='validate_cpu':F.save(output/'validation.json',dict(fixture=True))
|
||||
else:
|
||||
if kind=='brain':case=Path(job['case_dir'])
|
||||
elif kind=='oracle':case=Path(job['oracle_case'])
|
||||
else:case=Path(F.read(job['authority_file'])['case']['spec']['path']).parent
|
||||
spec=F.read(case/'spec.json')
|
||||
self.checkpoint(output,spec['steps'],job.get('diagnostic_mode','reference'),spec.get('global_tick_offset',0))
|
||||
result['checkpoint_manifest_sha256']=F.digest(output/'checkpoint-manifest.json')
|
||||
receipt=dict(output_dir=str(output),result=result)
|
||||
loc=self.exp/'receipts'/f'{name}.fixture-process.json';F.save(loc,dict(name=name,fixture=True))
|
||||
self.w.jobs[name]=dict(loc=dict(process=str(loc)),job=job,receipt=receipt)
|
||||
self.put(self.exp/'extension-build/.ninja_log',str(len(self.launched)))
|
||||
self.put(self.exp/'extension-build/new-extension.bin','compiled fixture artifact')
|
||||
return receipt
|
||||
|
||||
def test_new_job_exact_schema_and_direct_authority_parent_closure(self):
|
||||
cp=self.base/'AP-D1'
|
||||
auth=self.exp/'authorities/test.json'
|
||||
file=self.base/'binding.txt';self.put(file,'bound')
|
||||
F.save(auth,dict(parent=dict(directory=str(cp),checkpoint_manifest_sha256=F.digest(cp/'checkpoint-manifest.json')),
|
||||
files=dict(x=F.A.pin(file)),frozen_inputs={str(self.ap_worker):F.digest(self.ap_worker)}))
|
||||
job=self.w.new_job('test','updated',auth,build_root=str(self.exp/'extension-build'),diagnostic_mode='light')
|
||||
self.assertEqual(set(job),F.W.COMMON | F.W.FIELDS['updated'])
|
||||
self.assertEqual(set(job['source_sha256']),F.W.SOURCES['updated'])
|
||||
for path in (file,auth,cp/'checkpoint-manifest.json',self.exp/'protocol/preregistered.json'):
|
||||
self.assertEqual(job['input_sha256'][str(path)],F.digest(path))
|
||||
sample=self.w.new_job('evaluation-inputs','sample',self.exp/'protocol/preregistered.json')
|
||||
self.assertEqual(set(sample),F.W.COMMON | F.W.FIELDS['sample'])
|
||||
self.assertEqual(set(sample['source_sha256']),F.W.SOURCES['sample'])
|
||||
|
||||
def test_full_fixed_workflow_23_brains_31_processes_and_shared_case_lineage(self):
|
||||
with patch.object(self.w,'launch',side_effect=self.fake_launch),patch.object(F.A,'boundary_authority',side_effect=self.fake_boundary):
|
||||
self.w.run()
|
||||
self.assertEqual(len(self.w.completed),23);self.assertEqual(len(self.w.jobs),31)
|
||||
self.assertEqual(len(list((self.exp/'cases').iterdir())),17)
|
||||
byname={n:j for n,j,_ in self.launched}
|
||||
for _,job,ap in self.launched:
|
||||
expected=self.ap.COMMON | (self.ap.BRAIN_FIELDS if job['kind']=='brain' else self.ap.UPDATE_FIELDS) if ap else F.W.COMMON | F.W.FIELDS[job['kind']]
|
||||
self.assertEqual(set(job),expected)
|
||||
self.assertEqual(sum(j['kind'] in ('brain','updated','oracle','unchanged') for j in byname.values()),23)
|
||||
self.assertEqual(sum(j['kind']=='sample' for j in byname.values()),1)
|
||||
for arm in ('D1','D0','frozen','mechanical'):
|
||||
r=F.read(byname[f'{arm}--updated--reference']['authority_file'])
|
||||
l=F.read(byname[f'{arm}--updated--light']['authority_file'])
|
||||
self.assertEqual(r['case'],l['case']);self.assertEqual(r['parent'],l['parent'])
|
||||
for arm in ('D0','frozen'):
|
||||
job=byname[f'{arm}--old-C--reference'];p=self.reg['parent_records'][f'AP.{arm}.reference.epoch001']
|
||||
self.assertEqual(job['overlay_file'],p['before_overlay']['overlay_file'])
|
||||
self.assertNotEqual(job['overlay_file'],p['after_overlay']['overlay_file'])
|
||||
for arm in ('D1','mechanical'):
|
||||
self.assertEqual(byname[f'{arm}--live-oracle']['authority_file'],byname[f'{arm}--updated--reference']['authority_file'])
|
||||
after=self.reg['parent_records']['AP.D1.reference.epoch001']['after_overlay']
|
||||
idle=next(v for v in self.boundary_args if v['boundary_id']=='D1--idle--9s')
|
||||
self.assertEqual(idle['before_overlay'],after);self.assertEqual(idle['after_overlay'],after)
|
||||
self.assertIsNone(idle['epoch']);self.assertIsNone(idle['update_dir']);self.assertIsNone(idle['cpu_receipt'])
|
||||
self.assertEqual(self.w.parents['D1--idle--9s']['after_overlay'],after)
|
||||
for t in ('t0','t1','t10'):
|
||||
for cue,node in (('A',20),('B',30)):
|
||||
request=F.npz(self.exp/'cases'/f'D1--probe--{t}--{cue}'/'requests.npz')
|
||||
np.testing.assert_array_equal(request['neuron_idx'],np.array([node],np.int32))
|
||||
performance=byname['performance--natural-light-fresh']
|
||||
prior=self.reg['parent_records']['AP.D1.reference.epoch001']
|
||||
self.assertEqual(performance['overlay_file'],prior['before_overlay']['overlay_file'])
|
||||
update=F.read(byname['performance--natural-light-fresh--original-E']['authority_file'])
|
||||
self.assertEqual((update['command']['us_tick'],update['command']['trace_backend'],update['diagnostic_mode']),(900,'torch','light'))
|
||||
self.assertIn('performance--natural-light-fresh--cpu-verify',byname)
|
||||
cpu=byname['performance--natural-light-fresh--cpu-verify']
|
||||
self.assertEqual(cpu['authority_file'],byname['performance--natural-light-fresh--original-E']['authority_file'])
|
||||
self.assertEqual(cpu['update_dir'],byname['performance--natural-light-fresh--original-E']['output_dir'])
|
||||
for output in Path(cpu['update_dir']).iterdir():
|
||||
self.assertEqual(cpu['input_sha256'][str(output)],F.digest(output))
|
||||
probe=byname['performance--evaluation-A-light-fresh']
|
||||
self.assertEqual(probe['overlay_file'],self.initial['overlay_file'])
|
||||
self.assertNotIn('parent_checkpoint_manifest_sha256',F.read(Path(probe['case_dir'])/'spec.json'))
|
||||
self.assertFalse(any(n.startswith('performance--evaluation-A-light-fresh--') for n in byname))
|
||||
complete=F.read(self.exp/'audit/execution-complete.json')
|
||||
self.assertFalse(complete['scientific_learning_pass_claimed'])
|
||||
|
||||
def test_mutable_build_inventory_visible_new_artifacts_not_silently_ignored(self):
|
||||
self.w.reg=deepcopy(self.reg)
|
||||
self.w.reg['plan']=dict(imported_parents={},calls=self.plan['calls'][:2],
|
||||
counts=dict(new_brain_calls=2,total_children=0))
|
||||
def execute(call):
|
||||
self.put(self.exp/'extension-build/.ninja_log',call['call_id'])
|
||||
self.put(self.exp/'extension-build/new-extension.bin','compiled fixture artifact')
|
||||
F.save(self.exp/'runs'/(call['call_id']+'.json'),dict(complete=True))
|
||||
with patch.object(self.w,'execute_call',side_effect=execute):
|
||||
self.w.run()
|
||||
self.assertNotIn('extension-build/.ninja_log',F.tree(self.exp,exclude_build=True))
|
||||
self.assertIn('extension-build/.ninja_log',F.tree(self.exp))
|
||||
for cycle in self.w.cycles:
|
||||
self.assertIn('.ninja_log',cycle['mutable_build_inventory_after'])
|
||||
self.assertIn('new-extension.bin',cycle['mutable_build_inventory_after'])
|
||||
self.assertGreater(cycle['mutable_build_bytes_after'],0)
|
||||
self.assertTrue(cycle['output_inventory'])
|
||||
old=self.exp/'audit/pinned-result.json';F.save(old,dict(value=1))
|
||||
before=F.tree(self.exp,exclude_build=True);self.put(old,'{"value":2}')
|
||||
after=F.tree(self.exp,exclude_build=True)
|
||||
self.assertNotEqual(before['audit/pinned-result.json'],after['audit/pinned-result.json'])
|
||||
|
||||
def test_probe_scope_mutation_rejected_and_shared_case_mismatch_rejected(self):
|
||||
call=deepcopy(self.calls['performance--evaluation-A-light-fresh']);call['US']=True
|
||||
with self.assertRaises(ValueError):self.w.execute_call(call)
|
||||
call=self.calls['D1--updated--reference'];parent=self.w.parents[call['parent']]
|
||||
case=self.w.materialize(call,parent)
|
||||
altered=deepcopy(parent);altered['checkpoint_sha256']='0'*64
|
||||
with self.assertRaises(ValueError):self.w.materialize(call,altered)
|
||||
self.assertEqual(F.read(case/'spec.json')['parent_checkpoint_manifest_sha256'],parent['checkpoint_sha256'])
|
||||
|
||||
def child_receipt(self,command,*,ap=False,mutate=None,**kwargs):
|
||||
jobfile=Path(command[command.index('--job')+1]);job=F.read(jobfile)
|
||||
out=Path(job['output_dir']);out.mkdir();F.save(out/'result.json',dict(fixture=True))
|
||||
attempt=Path(job['receipt_file']+'.attempt.json');F.save(attempt,dict(fixture=True))
|
||||
script=self.ap_worker if ap else self.model/'isolated_execution.py'
|
||||
pins={**job['input_sha256'],str(jobfile):F.digest(jobfile),str(script):job['worker_sha256']}
|
||||
if ap:pins.update({v['path']:v['sha256'] for v in job['sources'].values()})
|
||||
else:
|
||||
pins[str(self.ap_worker)]=F.W.AP_SHA
|
||||
pins.update({str(self.model/k):v for k,v in job['source_sha256'].items()})
|
||||
receipt=dict(schema='phase4ap-isolated-worker-receipt-v1' if ap else 'conditioning-isolated-execution-receipt-v1',
|
||||
complete=True,job_sha256=F.digest(jobfile),registration_sha256=self.w.sha,kind=job['kind'],
|
||||
job_id=job['job_id'],worker_sha256=job['worker_sha256'],output_dir=job['output_dir'],
|
||||
output_files_sha256={'result.json':F.digest(out/'result.json')},attempt_sha256=F.digest(attempt))
|
||||
receipt['verified_input_sha256' if ap else 'input_sha256']=pins
|
||||
if mutate:mutate(receipt)
|
||||
F.save(job['receipt_file'],receipt)
|
||||
return SimpleNamespace(returncode=0)
|
||||
|
||||
def sample_job(self,name):
|
||||
return self.w.new_job(name,'sample',self.exp/'protocol/preregistered.json')
|
||||
|
||||
def test_real_parent_process_receipt_binds_exit_inputs_outputs_and_wall_layers(self):
|
||||
job=self.sample_job('success')
|
||||
with patch.object(self.w,'admission'),patch.object(F,'verify'), \
|
||||
patch.object(F.subprocess,'run',side_effect=self.child_receipt) as run, \
|
||||
patch.object(F.time,'perf_counter',side_effect=[100.,104.,107.]):
|
||||
self.w.deadline=110.;self.w.launch('success',job)
|
||||
process=F.read(self.exp/'receipts/success.process.json')
|
||||
self.assertEqual((process['exit_code'],process['child_wall_seconds'],process['validation_wall_seconds'],process['end_to_end_seconds']),(0,4.,3.,7.))
|
||||
self.assertEqual(run.call_args.kwargs['timeout'],10.)
|
||||
self.assertEqual(process['worker_receipt_sha256'],F.digest(self.exp/'receipts/success.worker.json'))
|
||||
self.assertGreater(process['output_bytes'],0)
|
||||
self.assertTrue(process['complete'])
|
||||
|
||||
def test_frozen_AP_worker_parent_receipt_uses_verified_source_closure(self):
|
||||
prior=self.reg['parent_records']['AP.D1.reference.epoch001']
|
||||
case=Path(F.read(prior['epoch_authority']['path'])['files']['requests']['path']).parent
|
||||
job=self.w.ap_job('performance-ap','brain',case=case,overlay=prior['before_overlay'],output=self.exp/'runs/performance-ap')
|
||||
self.assertEqual(set(job),self.ap.COMMON | self.ap.BRAIN_FIELDS)
|
||||
with patch.object(self.w,'admission'),patch.object(F,'verify'), \
|
||||
patch.object(F.subprocess,'run',side_effect=lambda *a,**kw:self.child_receipt(*a,ap=True,**kw)) as run:
|
||||
self.w.launch('performance-ap',job,ap=True)
|
||||
self.assertEqual(run.call_args.args[0][3],'brain')
|
||||
receipt=F.read(self.exp/'receipts/performance-ap.worker.json')
|
||||
for role in ('runtime_light','runtime_continuation'):
|
||||
binding=job['sources'][role]
|
||||
self.assertEqual(receipt['verified_input_sha256'][binding['path']],binding['sha256'])
|
||||
|
||||
def test_exit_failure_timeout_and_receipt_mutation_preserved_and_not_retried(self):
|
||||
variants=[('exit',lambda *a,**kw:SimpleNamespace(returncode=9)),
|
||||
('timeout',lambda *a,**kw:(_ for _ in ()).throw(subprocess.TimeoutExpired('fixture',1))),
|
||||
('identity',lambda *a,**kw:self.child_receipt(*a,mutate=lambda r:r.update(job_id='wrong'),**kw)),
|
||||
('closure',lambda *a,**kw:self.child_receipt(*a,mutate=lambda r:r['input_sha256'].clear(),**kw)),
|
||||
('output',lambda *a,**kw:self.child_receipt(*a,mutate=lambda r:r['output_files_sha256'].clear(),**kw))]
|
||||
for name,action in variants:
|
||||
job=self.sample_job(name)
|
||||
with patch.object(self.w,'admission'),patch.object(F,'verify'),patch.object(F.subprocess,'run',side_effect=action) as run:
|
||||
with self.assertRaises(ValueError):self.w.launch(name,job)
|
||||
self.assertFalse(F.read(self.exp/f'receipts/{name}.process.json')['complete'])
|
||||
with self.assertRaises(ValueError):self.w.launch(name,job)
|
||||
self.assertEqual(run.call_count,1)
|
||||
self.assertNotIn(name,self.w.jobs)
|
||||
|
||||
def test_workflow_attempt_prevents_restart(self):
|
||||
F.save(self.exp/'audit/execution-attempt.json',dict(partial=True))
|
||||
with patch.object(self.w,'cpu_verify') as verify:
|
||||
with self.assertRaises(ValueError):self.w.run()
|
||||
verify.assert_not_called()
|
||||
|
||||
def test_whole_deadline_starts_before_registration_verification(self):
|
||||
clock=[10.]
|
||||
def registration(sha):clock[0]=50.;return self.reg
|
||||
with patch.object(F,'registration',side_effect=registration),patch.object(F.W,'ap_helpers',return_value=self.w.h), \
|
||||
patch.object(F.time,'perf_counter',side_effect=lambda:clock[0]):
|
||||
workflow=F.Workflow('a'*64)
|
||||
self.assertEqual(workflow.started,10.)
|
||||
self.assertEqual(workflow.deadline,10.+self.reg['budget']['workflow_timeout_seconds'])
|
||||
|
||||
def test_no_complete_after_final_cycle_inventory_crosses_deadline(self):
|
||||
call=self.calls['D1--updated--reference'];self.w.reg=deepcopy(self.reg)
|
||||
self.w.reg['plan']=dict(imported_parents={},calls=[call],counts=dict(new_brain_calls=1,total_children=0))
|
||||
clock=[1.];self.w.started=0.;self.w.deadline=5.
|
||||
def execute(_):clock[0]=6.
|
||||
with patch.object(self.w,'execute_call',side_effect=execute),patch.object(F.time,'perf_counter',side_effect=lambda:clock[0]):
|
||||
with self.assertRaisesRegex(ValueError,'wall limit'):
|
||||
self.w.run()
|
||||
self.assertFalse((self.exp/'audit/execution-complete.json').exists())
|
||||
|
||||
def test_import_does_not_load_old_coordinator_neural_runtime_or_torch(self):
|
||||
code="import sys;sys.path.insert(0,sys.argv[1]);import execution_workflow;bad=[k for k in sys.modules if k in ('torch','runtime_light','runtime_continuation','conditioning_epoch','_conditioning_execution_prior_integrity')];assert not bad,bad"
|
||||
completed=subprocess.run([sys.executable,'-B','-c',code,str(Path(__file__).resolve().parent)],
|
||||
capture_output=True,text=True,timeout=20)
|
||||
self.assertEqual(completed.returncode,0,completed.stderr)
|
||||
|
||||
|
||||
if __name__=='__main__':unittest.main()
|
||||
@@ -0,0 +1,147 @@
|
||||
"""Synthetic seal checks only; no historical integrity or brain execution."""
|
||||
import copy
|
||||
from contextlib import contextmanager
|
||||
import json
|
||||
from pathlib import Path
|
||||
import tempfile
|
||||
from types import SimpleNamespace
|
||||
import unittest
|
||||
from unittest.mock import Mock, patch
|
||||
import finalize_execution as F
|
||||
|
||||
|
||||
class FinalizeTests(unittest.TestCase):
|
||||
@contextmanager
|
||||
def complete_fixture(self):
|
||||
"""Temporary evidence + mocked auditors/child; no real integrity run."""
|
||||
helper = Path(__file__).parents[1]/'pn-recruitment-audit-v1/publication.py'
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
root = Path(tmp).resolve()
|
||||
for folder in ('protocol', 'audit', 'regression'):
|
||||
(root/folder).mkdir()
|
||||
reg = dict(schema='conditioning-execution-registration-v1', engineering_only=True,
|
||||
scientific_acquisition_authorized=False, source_sha256={}, input_sha256={},
|
||||
prepared_file_sha256={}, source_code_commit='a'*40)
|
||||
F.save(root/'protocol/preregistered.json', reg)
|
||||
regsha = F.digest(root/'protocol/preregistered.json')
|
||||
numerical = dict(schema='conditioning-execution-numerical-audit-v1', complete=True,
|
||||
registration_sha256=regsha, actual_new_brain_calls=23, actual_processes=31,
|
||||
actual_new_brain_ticks=125200, learning_pass_claimed=False, candidate_generated=False,
|
||||
status='PASS-EXACT-UPDATED-BOUNDARY-ENGINEERING-NOT-LEARNING', pass_all=True,
|
||||
process_evidence={'synthetic': {'worker_sha256':'b'*64}})
|
||||
budget = dict(schema='synthetic-budget-report-not-scientific', complete=True,
|
||||
registration_sha256=regsha, learning_pass_claimed=False, measured_fixture_seconds=1.)
|
||||
integrity = dict(complete=True, AP={'pass_all':True}, prior={'synthetic_old_roots':'unchanged'},
|
||||
anchors={'synthetic_reference':'c'*64}, old_experiments_reexecuted=False,
|
||||
old_files_modified=False, five_frozen_reference_trials_rerun_here=False,
|
||||
scientific_learning_pass_claimed=False)
|
||||
files = (root/'audit/numerical-comparison.json', root/'audit/budget-report.json',
|
||||
root/'regression/integrity-after.json')
|
||||
for file, value in zip(files, (numerical, budget, integrity)):
|
||||
F.save(file, value)
|
||||
numerical_module = SimpleNamespace(audit=Mock(return_value=copy.deepcopy(numerical)),
|
||||
same_json=lambda a,b: json.dumps(a,sort_keys=True,allow_nan=False)==json.dumps(b,sort_keys=True,allow_nan=False))
|
||||
budget_module = SimpleNamespace(report=Mock(return_value=copy.deepcopy(budget)))
|
||||
def child(command, **kwargs):
|
||||
self.assertEqual(command, [F.sys.executable,'-B',str(F.MODEL/'prepare_execution.py'),
|
||||
'integrity','--output',str(root/'regression/integrity-at-seal.json')])
|
||||
self.assertEqual(kwargs, dict(cwd=F.MODEL,capture_output=True,text=True,timeout=1800))
|
||||
F.save(root/'regression/integrity-at-seal.json', integrity)
|
||||
return SimpleNamespace(returncode=0, stdout='synthetic child', stderr='')
|
||||
with patch.object(F,'EXP',root),patch.object(F,'HELPER',helper), \
|
||||
patch.dict(F.sys.modules,{'audit_execution':numerical_module,'budget_report':budget_module}), \
|
||||
patch.object(F.subprocess,'run',side_effect=child) as process:
|
||||
yield SimpleNamespace(root=root, numerical=numerical, integrity=integrity,
|
||||
audit_module=numerical_module,budget_module=budget_module,process=process,
|
||||
args=(regsha,*(F.digest(p) for p in files)))
|
||||
|
||||
def test_source_helper_matches_actual_local_frozen_file(self):
|
||||
path = Path(__file__).parents[1]/'pn-recruitment-audit-v1/publication.py'
|
||||
with patch.object(F, 'HELPER', path):
|
||||
module = F.helper()
|
||||
self.assertTrue(callable(module.verify_seal))
|
||||
|
||||
def test_exact_seal_detects_mutated_and_extra_payload(self):
|
||||
path = Path(__file__).parents[1]/'pn-recruitment-audit-v1/publication.py'
|
||||
with tempfile.TemporaryDirectory() as tmp, patch.object(F, 'HELPER', path):
|
||||
root = Path(tmp)
|
||||
F.save(root/'one.json', {'learning':False})
|
||||
result = F.seal(root)
|
||||
self.assertTrue(result['pass_all'])
|
||||
self.assertEqual(result['payload_file_count'], 1)
|
||||
with self.assertRaisesRegex(ValueError, 'Never replace'):
|
||||
F.seal(root)
|
||||
F.save(root/'unlisted.json', {})
|
||||
with self.assertRaisesRegex(ValueError, 'unlisted/missing'):
|
||||
F.helper().verify_seal(root)
|
||||
|
||||
def test_refuses_empty_and_bytecode_trees(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
root = Path(tmp)
|
||||
with self.assertRaisesRegex(ValueError, 'Empty'):
|
||||
F.seal(root)
|
||||
(root/'__pycache__').mkdir()
|
||||
with self.assertRaisesRegex(ValueError, 'Unsafe'):
|
||||
F.seal(root)
|
||||
|
||||
def test_stopped_workflow_never_gets_normal_final(self):
|
||||
with tempfile.TemporaryDirectory() as tmp, patch.object(F, 'EXP', Path(tmp)):
|
||||
(Path(tmp)/'audit').mkdir()
|
||||
F.save(Path(tmp)/'audit/stopped.json', {'complete':False})
|
||||
with self.assertRaisesRegex(ValueError, 'separate explicit failure audit'):
|
||||
F.finalize('a'*64, 'b'*64, 'c'*64, 'd'*64)
|
||||
|
||||
def test_full_mock_finalize_recomputes_and_seals_actual_independent_report(self):
|
||||
with self.complete_fixture() as fixture:
|
||||
result = F.finalize(*fixture.args)
|
||||
fixture.audit_module.audit.assert_called_once_with(fixture.args[0],save_report=False)
|
||||
fixture.budget_module.report.assert_called_once_with(fixture.args[0],save_report=False)
|
||||
fixture.process.assert_called_once()
|
||||
final = F.read(fixture.root/'audit/final-status.json')
|
||||
self.assertEqual(result['status'],'PASS-EXACT-UPDATED-BOUNDARY-ENGINEERING-NOT-LEARNING')
|
||||
self.assertEqual(final['integrity_at_seal_sha256'],F.digest(fixture.root/'regression/integrity-at-seal.json'))
|
||||
self.assertTrue(final['numerical_and_budget_recomputed_at_seal'])
|
||||
self.assertFalse(final['scientific_acquisition_executed'])
|
||||
self.assertFalse(final['learning_pass_claimed']); self.assertFalse(final['candidate_generated'])
|
||||
self.assertEqual(final['historical_five_trial_regression'],'AM sealed evidence preserved; not rerun here')
|
||||
sealed = F.helper().verify_seal(fixture.root)
|
||||
self.assertTrue(sealed['pass_all'])
|
||||
payload = {row['path'] for row in F.read(fixture.root/'manifest.json')['files']}
|
||||
self.assertTrue({'audit/numerical-comparison.json','audit/budget-report.json',
|
||||
'regression/integrity-after.json','regression/integrity-at-seal.json',
|
||||
'audit/final-status.json'}.issubset(payload))
|
||||
|
||||
def test_recomputed_numerical_or_budget_mutation_rejected_before_integrity_and_seal(self):
|
||||
for kind in ('numerical','budget'):
|
||||
with self.subTest(kind=kind),self.complete_fixture() as fixture:
|
||||
if kind=='numerical':
|
||||
changed=copy.deepcopy(fixture.numerical)
|
||||
changed['process_evidence']['synthetic']['worker_sha256']='d'*64
|
||||
fixture.audit_module.audit.return_value=changed
|
||||
else:
|
||||
changed=copy.deepcopy(fixture.budget_module.report.return_value)
|
||||
changed['measured_fixture_seconds']=2.
|
||||
fixture.budget_module.report.return_value=changed
|
||||
with self.assertRaisesRegex(ValueError,'evidence changed after the independent audit'):
|
||||
F.finalize(*fixture.args)
|
||||
fixture.process.assert_not_called()
|
||||
for name in ('audit/final-status.json','manifest.json','checksums.sha256'):
|
||||
self.assertFalse((fixture.root/name).exists())
|
||||
|
||||
def test_independent_integrity_failure_missing_output_or_changed_prior_refuses_seal(self):
|
||||
for mode in ('nonzero_exit','missing_file','changed_prior'):
|
||||
with self.subTest(mode=mode),self.complete_fixture() as fixture:
|
||||
def child(*args,**kwargs):
|
||||
if mode=='changed_prior':
|
||||
changed=copy.deepcopy(fixture.integrity); changed['prior']['synthetic_old_roots']='changed'
|
||||
F.save(fixture.root/'regression/integrity-at-seal.json',changed)
|
||||
return SimpleNamespace(returncode=1 if mode=='nonzero_exit' else 0,stdout='',stderr='synthetic failure')
|
||||
fixture.process.side_effect=child
|
||||
with self.assertRaisesRegex(ValueError,'integrity-at-seal process failed|Frozen integrity changed'):
|
||||
F.finalize(*fixture.args)
|
||||
for name in ('audit/final-status.json','manifest.json','checksums.sha256'):
|
||||
self.assertFalse((fixture.root/name).exists())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -0,0 +1,176 @@
|
||||
"""CPU/path/admission tests only; no subprocess brain or scientific PASS."""
|
||||
import copy
|
||||
import json
|
||||
from pathlib import Path
|
||||
import tempfile
|
||||
from types import SimpleNamespace
|
||||
import unittest
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
import isolated_execution as W
|
||||
|
||||
H = W.ap_helpers()
|
||||
|
||||
|
||||
class WorkerTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.temp = tempfile.TemporaryDirectory()
|
||||
self.root = Path(self.temp.name).resolve() / 'phase4aq-fixture'
|
||||
for name in ('inputs', 'updates', 'jobs', 'runs', 'receipts'):
|
||||
(self.root / name).mkdir(parents=True)
|
||||
self.authority = self.root / 'inputs' / 'authority.json'
|
||||
self.chain = self.root / 'updates' / 'chain-receipt.json'
|
||||
self.authority.write_text('{}'); self.chain.write_text('{}')
|
||||
self.jobfile = self.root / 'jobs' / 'one.json'
|
||||
self.job = dict(schema=W.SCHEMA, job_id='cpu-one', kind='validate_cpu',
|
||||
registration_sha256='1'*64, worker_sha256=H.digest(W.__file__),
|
||||
source_sha256={'validate_update_cpu.py': H.digest(W.MODEL/'validate_update_cpu.py')},
|
||||
input_sha256={str(p): H.digest(p) for p in (self.authority, self.chain)},
|
||||
output_dir=str(self.root/'runs'/'one'), receipt_file=str(self.root/'receipts'/'one.json'),
|
||||
budget=dict(root=str(self.root), output_cap_bytes=1024**2, minimum_free_reserve_bytes=1024**2),
|
||||
authority_file=str(self.authority), authority_sha256=H.digest(self.authority),
|
||||
update_dir=str(self.chain.parent), chain_sha256=H.digest(self.chain))
|
||||
|
||||
def tearDown(self):
|
||||
self.temp.cleanup()
|
||||
|
||||
def check(self, job=None):
|
||||
self.jobfile.write_text(json.dumps(self.job if job is None else job))
|
||||
return W.validate_job(H, self.jobfile, H.digest(self.jobfile))
|
||||
|
||||
def test_real_pinned_AP_helper_and_CPU_job(self):
|
||||
self.assertEqual(H.digest(W.AP), W.AP_SHA)
|
||||
job, paths, pins = self.check()
|
||||
self.assertEqual(job['kind'], 'validate_cpu')
|
||||
self.assertEqual(pins[W.AP], W.AP_SHA)
|
||||
self.assertEqual(paths['output'], self.root/'runs'/'one')
|
||||
|
||||
def test_wrong_or_missing_fields(self):
|
||||
changes = [('kind', 'brain'), ('job_id', '../x'), ('job_id', 'a/b'),
|
||||
('registration_sha256', ''), ('worker_sha256', '0'*64),
|
||||
('source_sha256', {}), ('input_sha256', {})]
|
||||
for key, value in changes:
|
||||
with self.subTest(key=key, value=value):
|
||||
job = copy.deepcopy(self.job); job[key] = value
|
||||
with self.assertRaises(ValueError): self.check(job)
|
||||
job = copy.deepcopy(self.job); job['extra'] = True
|
||||
with self.assertRaises(ValueError): self.check(job)
|
||||
|
||||
def test_source_bytes_are_checked_before_import(self):
|
||||
job = copy.deepcopy(self.job); job['source_sha256']['validate_update_cpu.py'] = '0'*64
|
||||
with self.assertRaisesRegex(ValueError, 'Pinned file changed'): self.check(job)
|
||||
|
||||
def test_parent_input_pin_and_chain_are_mandatory(self):
|
||||
for key in ('authority_sha256', 'chain_sha256'):
|
||||
job = copy.deepcopy(self.job); job[key] = '0'*64
|
||||
with self.subTest(key=key), self.assertRaises(ValueError): self.check(job)
|
||||
job = copy.deepcopy(self.job); del job['input_sha256'][str(self.chain)]
|
||||
with self.assertRaises(ValueError): self.check(job)
|
||||
|
||||
def test_partial_output_and_attempt_never_retried(self):
|
||||
output = Path(self.job['output_dir']); output.mkdir()
|
||||
with self.assertRaises(ValueError): self.check()
|
||||
output.rmdir()
|
||||
attempt = Path(self.job['receipt_file']+'.attempt.json'); attempt.write_text('{}')
|
||||
with self.assertRaises(ValueError): self.check()
|
||||
|
||||
def test_output_cannot_overlap_input_update_or_receipt(self):
|
||||
for path in (self.authority.parent/'child', self.chain.parent/'child',
|
||||
self.root/'receipts'/'child', self.root.parent/'escape'):
|
||||
job = copy.deepcopy(self.job); job['output_dir'] = str(path)
|
||||
with self.subTest(path=path), self.assertRaises(ValueError): self.check(job)
|
||||
|
||||
def test_linked_output_parent_rejected_when_supported(self):
|
||||
target = self.root/'runs'; linked = self.root/'linked'
|
||||
try: linked.symlink_to(target, target_is_directory=True)
|
||||
except OSError: self.skipTest('Platform does not allow test symlinks')
|
||||
job = copy.deepcopy(self.job); job['output_dir'] = str(linked/'one')
|
||||
with self.assertRaisesRegex(ValueError, 'Linked'): self.check(job)
|
||||
|
||||
def test_explicit_resource_limits(self):
|
||||
job, paths, _ = self.check()
|
||||
result = W.budget_check(H, job, paths)
|
||||
self.assertGreater(result['output_bytes'], 0)
|
||||
job['budget']['output_cap_bytes'] = 1
|
||||
with self.assertRaisesRegex(ValueError, 'Resource budget exceeded'): W.budget_check(H, job, paths)
|
||||
for field in ('output_cap_bytes', 'minimum_free_reserve_bytes'):
|
||||
job = copy.deepcopy(self.job); job['budget'][field] = 0
|
||||
with self.subTest(field=field), self.assertRaises(ValueError): self.check(job)
|
||||
|
||||
def test_fresh_process_loaders_are_not_reused(self):
|
||||
with self.assertRaisesRegex(ValueError, 'Fresh exec helper'): W.ap_helpers()
|
||||
|
||||
def unchanged(self):
|
||||
case=self.root/'inputs'/'case';case.mkdir()
|
||||
parent=self.root/'inputs'/'checkpoint';parent.mkdir()
|
||||
for p in (case/'spec.json',case/'requests.npz',parent/'checkpoint-manifest.json'):
|
||||
p.write_text('{}')
|
||||
before=self.root/'inputs'/'before.npz';bm=self.root/'inputs'/'before.json'
|
||||
after=self.root/'inputs'/'after.npz';am=self.root/'inputs'/'after.json'
|
||||
before.write_bytes(b'zero-values');after.write_bytes(b'zero-values')
|
||||
bm.write_text('{"phase":"before"}');am.write_text('{"phase":"after"}')
|
||||
files=(case/'spec.json',case/'requests.npz',parent/'checkpoint-manifest.json',before,bm,after,am,W.C_PATH)
|
||||
authority=dict(schema='conditioning-updated-boundary-v1',transition='epoch_update',diagnostic_mode='reference',
|
||||
registration_sha256='1'*64,expected_effective_weight_before_sha256='a'*64,expected_effective_weight_after_sha256='a'*64,
|
||||
parent=dict(directory=str(parent),checkpoint_manifest_sha256=H.digest(parent/'checkpoint-manifest.json')),
|
||||
case={key:dict(path=str(case/name),sha256=H.digest(case/name)) for key,name in (('spec','spec.json'),('requests','requests.npz'))},
|
||||
overlay_before={key:dict(path=str(p),sha256=H.digest(p)) for key,p in (('file',before),('manifest',bm))},
|
||||
overlay_after={key:dict(path=str(p),sha256=H.digest(p)) for key,p in (('file',after),('manifest',am))},frozen_inputs={})
|
||||
self.authority.write_text(json.dumps(authority))
|
||||
self.job=dict(schema=W.SCHEMA,job_id='unchanged-one',kind='unchanged',registration_sha256='1'*64,
|
||||
worker_sha256=H.digest(W.__file__),source_sha256={},input_sha256={str(p):H.digest(p) for p in (*files,self.authority)},
|
||||
output_dir=str(self.root/'runs'/'one'),receipt_file=str(self.root/'receipts'/'one.json'),
|
||||
budget=dict(root=str(self.root),output_cap_bytes=1024**2,minimum_free_reserve_bytes=1024**2),
|
||||
authority_file=str(self.authority),authority_sha256=H.digest(self.authority),case_dir=str(case),
|
||||
build_root=str(self.root/'build'),diagnostic_mode='reference',overlay_file=str(before),overlay_manifest=str(bm),
|
||||
checkpoint_dir=str(parent),checkpoint_sha256=H.digest(parent/'checkpoint-manifest.json'))
|
||||
return authority
|
||||
|
||||
def test_unchanged_binds_exact_before_not_equal_after_manifest(self):
|
||||
self.unchanged();job,paths,pins=self.check()
|
||||
self.assertEqual(W.bind_unchanged_authority(H,job,paths,pins)['transition'],'epoch_update')
|
||||
self.job['overlay_file']=str(self.root/'inputs'/'after.npz')
|
||||
self.job['overlay_manifest']=str(self.root/'inputs'/'after.json')
|
||||
job,paths,pins=self.check()
|
||||
with self.assertRaisesRegex(ValueError,'actual before'):W.bind_unchanged_authority(H,job,paths,pins)
|
||||
|
||||
def test_rehashed_wrong_authority_parent_mode_case_registration_rejected(self):
|
||||
original=self.unchanged()
|
||||
for field in ('parent','diagnostic_mode','registration_sha256','case'):
|
||||
value=copy.deepcopy(original)
|
||||
if field=='parent':value[field]['checkpoint_manifest_sha256']='f'*64
|
||||
elif field=='diagnostic_mode':value[field]='light'
|
||||
elif field=='registration_sha256':value[field]='f'*64
|
||||
else:value[field]['requests']['sha256']='f'*64
|
||||
self.authority.write_text(json.dumps(value))
|
||||
self.job['authority_sha256']=self.job['input_sha256'][str(self.authority)]=H.digest(self.authority)
|
||||
job,paths,pins=self.check()
|
||||
with self.subTest(field=field),self.assertRaises(ValueError):W.bind_unchanged_authority(H,job,paths,pins)
|
||||
|
||||
def test_unchanged_missing_nested_after_authority_pin_rejected(self):
|
||||
self.unchanged();del self.job['input_sha256'][str(self.root/'inputs'/'after.json')]
|
||||
job,paths,pins=self.check()
|
||||
with self.assertRaisesRegex(ValueError,'external input pin'):W.bind_unchanged_authority(H,job,paths,pins)
|
||||
|
||||
def test_unchanged_original_entry_already_seals_no_double_seal(self):
|
||||
self.unchanged();self.check()
|
||||
summary={'apl_component':{'environment':{'synthetic':True}},'complete':True,'steps':5}
|
||||
def simulated_entry(case,out,build,overlay,manifest,parent,*,mode):
|
||||
out.mkdir();H.save_json(out/'summary.json',summary)
|
||||
H.save_json(out/'checkpoint-manifest.json',{'synthetic_seal':True})
|
||||
return dict(summary,checkpoint_manifest_sha256=H.digest(out/'checkpoint-manifest.json'))
|
||||
runtime=SimpleNamespace(run_continued=Mock(side_effect=simulated_entry),
|
||||
load_checkpoint=Mock(return_value={'summary':summary}),
|
||||
seal_checkpoint=Mock(side_effect=AssertionError('Double seal would be a real blocker')))
|
||||
with patch.object(W,'ap_helpers',return_value=H),patch.object(H,'_clean_process') as clean, \
|
||||
patch.object(H,'_admit_brain',return_value={'synthetic_no_GPU':True}), \
|
||||
patch.object(H,'_load_source',return_value=runtime),patch.object(H,'_environment',return_value={'synthetic_no_GPU':True}), \
|
||||
patch.object(H,'_verify_precision'):
|
||||
result=W.execute(self.jobfile,H.digest(self.jobfile))
|
||||
runtime.run_continued.assert_called_once();runtime.load_checkpoint.assert_called_once();runtime.seal_checkpoint.assert_not_called()
|
||||
clean.assert_called_once_with('brain');self.assertTrue(result['complete'])
|
||||
self.assertFalse(result['process_exit_independently_observed'])
|
||||
self.assertFalse(result['scientific_learning_pass_claimed'])
|
||||
|
||||
|
||||
if __name__ == '__main__': unittest.main()
|
||||
@@ -0,0 +1,424 @@
|
||||
"""CPU synthetic fixtures only: no real brain, file receipts or science data."""
|
||||
import copy
|
||||
import hashlib
|
||||
import json
|
||||
import unittest
|
||||
|
||||
import numpy as np
|
||||
|
||||
import learning_gates as g
|
||||
|
||||
|
||||
NODES = np.arange(6, dtype=np.int32)
|
||||
POPS = {'MBON': np.array([0, 1, 2], np.int32), 'legacyDownstream': NODES.copy(),
|
||||
'nonMBONDownstream': np.array([3, 4, 5], np.int32), 'MBON01': np.array([0], np.int32),
|
||||
'MBON12': np.array([1], np.int32)}
|
||||
C, N = g.M.CUES
|
||||
|
||||
|
||||
def sha(value):
|
||||
return hashlib.sha256(str(value).encode()).hexdigest()
|
||||
|
||||
|
||||
def registry():
|
||||
blocks = {}
|
||||
counter = 0
|
||||
for mode in g.M.MODES:
|
||||
for dan in g.M.DAN_TYPES:
|
||||
for cue in g.M.CUES:
|
||||
for rep in range(1, 6):
|
||||
block = f'{mode}/{dan}/{cue}/{rep}'
|
||||
base = 2**40 + counter * 10
|
||||
blocks[block] = dict(mode=mode, dan_type=dan, compartment_verbatim=g.DAN_COMPARTMENTS[dan],
|
||||
conditioned_cue=cue, replicate=rep,
|
||||
training_sources=[dict(stream_id=f'{block}/{split}/{assay}', seed=base + j, split=split)
|
||||
for j, (split, assay) in enumerate((('training', 'normal'), ('training', 'delayed'),
|
||||
('training', 'reversal'), ('design', 'order')))],
|
||||
evaluation_sources={cue: dict(stream_id=f'{block}/evaluation/{cue}', seed=base + 7 + j, split='evaluation')
|
||||
for j, cue in enumerate(g.M.CUES)},
|
||||
evaluation_input_sha256={cue: sha(f'{block}/input/{cue}') for cue in g.M.CUES})
|
||||
counter += 1
|
||||
return dict(schema=g.REGISTRY_SCHEMA, protocol_sha256=sha('synthetic-unregistered-protocol'),
|
||||
population_binding_sha256=sha('synthetic-population-binding'), nodes_raw_sha256=g.M._hash(NODES),
|
||||
population_membership_sha256=g.M.validate_populations(NODES, POPS)['membership_sha256'], blocks=blocks)
|
||||
|
||||
|
||||
def authority(reg):
|
||||
return dict(schema=g.AUTHORITY_SCHEMA, registry_sha256=g.descriptor_sha256(reg),
|
||||
verification_receipt_sha256=sha('SYNTHETIC-NOT-A-REAL-VERIFICATION'),
|
||||
execution_inventory_sha256=sha('SYNTHETIC-NOT-EXECUTED'), population_binding_sha256=reg['population_binding_sha256'])
|
||||
|
||||
|
||||
def state(direction=0, *, downstream=True, g_effect=True, offset=0):
|
||||
counts = [1, 1, 0, 1, 0, 0]
|
||||
if direction:
|
||||
counts[1 if direction > 0 else 0] += abs(direction)
|
||||
if downstream:
|
||||
counts[3] += abs(direction)
|
||||
events = sorted((10 + k * 20 + offset, i) for i, count in enumerate(counts) for k in range(count))
|
||||
conductance = np.zeros(6, np.float64)
|
||||
if direction and g_effect:
|
||||
conductance[0] = .002 * abs(direction)
|
||||
return dict(step=np.array([tick for tick, _ in events], np.int32),
|
||||
neuron_idx=np.array([i for _, i in events], np.int32), counts=np.array(counts, np.int32),
|
||||
v=np.full(6, -.052, np.float64), g=conductance, ref=np.zeros(6, np.int32))
|
||||
|
||||
|
||||
def states(conditioned=C, strength=0, *, neutral_strength=0, downstream=True):
|
||||
neutral = next(cue for cue in g.M.CUES if cue != conditioned)
|
||||
return {conditioned: state(strength, downstream=downstream), neutral: state(neutral_strength, downstream=downstream)}
|
||||
|
||||
|
||||
def pair(reg, block, label, values, *, delta, checkpoint, policy='common_frozen_reset'):
|
||||
return dict(schema=g.PAIR_SCHEMA, block_id=block, snapshot_id=f'{block}/{label}',
|
||||
receipt_sha256=sha(f'{block}/{label}/pair'),
|
||||
probe_receipt_sha256={cue: sha(f'{block}/{label}/probe/{cue}') for cue in g.M.CUES},
|
||||
evaluation_input_sha256=dict(reg['blocks'][block]['evaluation_input_sha256']),
|
||||
state_raw_sha256={cue: g.M.validate_state(values[cue], nodes=NODES, steps=1200)['hashes'] for cue in g.M.CUES},
|
||||
states=values, state_policy=policy, source_checkpoint_sha256=checkpoint, delta_sha256=delta,
|
||||
probe_steps=1200, cs_start_tick=0, cs_stop_tick_exclusive=1000, US_requested=False,
|
||||
weight_updates_enabled=False, feedback_to_training_or_idle=False)
|
||||
|
||||
|
||||
def rebind(pair_value):
|
||||
pair_value['state_raw_sha256'] = {cue: g.M.validate_state(pair_value['states'][cue], nodes=NODES, steps=1200)['hashes']
|
||||
for cue in g.M.CUES}
|
||||
|
||||
|
||||
def execution(block, arm, cue, *, initial=None):
|
||||
return dict(receipt_sha256=sha(f'{block}/{arm}/execution'), recording_verified=True, complete=True,
|
||||
completed_epochs=100, reinforcement_opportunities=50, terminal_pairings=50, epoch_duration_ms=120.,
|
||||
cs_duration_ms=100., us_tick=900, initial_delta_sha256=initial or sha('zero-delta'),
|
||||
terminal_delta_sha256=sha(f'{block}/{arm}/delta'), terminal_checkpoint_sha256=sha(f'{block}/{arm}/terminal'),
|
||||
neural_state_policy='fresh_epoch_delta_only', weight_rule='frozen_temporal_eligibility_v2', reinforced_cue=cue)
|
||||
|
||||
|
||||
def common(reg, block):
|
||||
value = reg['blocks'][block]
|
||||
return dict(replicate_id=block, replicate_unit='independent_training',
|
||||
training_stream_ids=[x['stream_id'] for x in value['training_sources']],
|
||||
evaluation_stream_ids=[value['evaluation_sources'][cue]['stream_id'] for cue in g.M.CUES])
|
||||
|
||||
|
||||
def blocks(reg, mode, dan, cue):
|
||||
return [key for key, value in reg['blocks'].items()
|
||||
if (value['mode'], value['dan_type'], value['conditioned_cue']) == (mode, dan, cue)]
|
||||
|
||||
|
||||
def reversal_rows(reg, mode='physiological', dan='PAM15', cue=C):
|
||||
rows = []
|
||||
neutral = next(x for x in g.M.CUES if x != cue)
|
||||
direction = 1 if dan == 'PAM15' else -1
|
||||
for block in blocks(reg, mode, dan, cue):
|
||||
acq = execution(block, 'acquisition', cue)
|
||||
executions = dict(acquisition=acq,
|
||||
reversal=execution(block, 'reversal', neutral, initial=acq['terminal_delta_sha256']),
|
||||
no_reversal=execution(block, 'no_reversal', cue, initial=acq['terminal_delta_sha256']))
|
||||
row = common(reg, block)
|
||||
row['execution'] = executions
|
||||
row['pre'] = pair(reg, block, 'pre', states(cue), delta=acq['initial_delta_sha256'], checkpoint=sha('reset'))
|
||||
values = dict(acquisition=states(cue, direction), reversal=states(cue, direction, neutral_strength=2 * direction),
|
||||
no_reversal=states(cue, 2 * direction))
|
||||
for arm, value in values.items():
|
||||
e = executions[arm]
|
||||
row[arm] = pair(reg, block, arm, value, delta=e['terminal_delta_sha256'], checkpoint=e['terminal_checkpoint_sha256'])
|
||||
rows.append(row)
|
||||
return rows
|
||||
|
||||
|
||||
def idle(block, branch, cue):
|
||||
source = execution(block, 'paired' if branch == 'trained' else 'frozen', cue)
|
||||
if branch == 'frozen':
|
||||
source['terminal_delta_sha256'] = source['initial_delta_sha256']
|
||||
checkpoints, previous = {}, source['terminal_checkpoint_sha256']
|
||||
for second in (0, 1, 10):
|
||||
current = sha(f'{block}/{branch}/idle-checkpoint/{second}')
|
||||
checkpoints[str(second)] = dict(checkpoint_sha256=current, parent_checkpoint_sha256=previous,
|
||||
elapsed_ticks=second * 10000, absolute_tick=1200 + second * 10000,
|
||||
delta_sha256=source['terminal_delta_sha256'], carry_sha256={key: sha(f'{block}/{branch}/{second}/{key}') for key in g.CARRY})
|
||||
previous = current
|
||||
return dict(source_checkpoint_sha256=source['terminal_checkpoint_sha256'], delta_sha256=source['terminal_delta_sha256'],
|
||||
idle_lineage_id=f'{block}/{branch}/idle10', idle_receipt_sha256=sha(f'{block}/{branch}/idle-receipt'),
|
||||
total_idle_ticks=100000, no_input=True, updates_disabled=True, reset_state=False,
|
||||
analytic_time_advance=False, one_second_is_prefix_of_ten_second=True, checkpoints=checkpoints, source_execution=source)
|
||||
|
||||
|
||||
def retention_rows(reg, mode='physiological', dan='PAM15', cue=C):
|
||||
rows = []
|
||||
direction = 1 if dan == 'PAM15' else -1
|
||||
for block in blocks(reg, mode, dan, cue):
|
||||
row = common(reg, block)
|
||||
row.update(execution={branch: idle(block, branch, cue) for branch in ('trained', 'frozen')}, pre={}, checkpoints={})
|
||||
for branch in ('trained', 'frozen'):
|
||||
e = row['execution'][branch]
|
||||
row['pre'][branch] = pair(reg, block, 'pre-' + branch, states(cue),
|
||||
delta=e['source_execution']['initial_delta_sha256'], checkpoint=sha('reset'))
|
||||
for second in (0, 1, 10):
|
||||
row['checkpoints'][str(second)] = {}
|
||||
for branch in ('trained', 'frozen'):
|
||||
e = row['execution'][branch]
|
||||
row['checkpoints'][str(second)][branch] = pair(reg, block, f'{branch}/{second}',
|
||||
states(cue, direction if branch == 'trained' else 0), delta=e['delta_sha256'],
|
||||
checkpoint=e['checkpoints'][str(second)]['checkpoint_sha256'], policy='continuous_checkpoint')
|
||||
rows.append(row)
|
||||
return rows
|
||||
|
||||
|
||||
def acquisition_rows(reg, mode='physiological', dan='PAM15', cue=C, assay='normal'):
|
||||
rows = []
|
||||
for block in blocks(reg, mode, dan, cue):
|
||||
row = common(reg, block)
|
||||
row.update(assay=assay, mode=mode, dan_type=dan, conditioned_cue=cue, arms={})
|
||||
for arm in g.M.ARMS:
|
||||
strength = (1 if dan == 'PAM15' else -1) if arm == 'paired' else 0
|
||||
metric = g.M.arm_metrics(states(cue), states(cue, strength), conditioned_cue=cue, nodes=NODES, populations=POPS)
|
||||
e = dict(complete=True, recording_verified=True, receipt_sha256=sha(f'{block}/{assay}/{arm}/execution'), assay=assay,
|
||||
epoch_duration_ms=180. if assay == 'delayed' else 120., cs_duration_ms=100., us_tick=1500 if assay == 'delayed' else 900,
|
||||
completed_epochs=150 if arm == 'unpaired' else 100, reinforcement_opportunities=0 if arm == 'CS-only' else 50, terminal_pairings=50)
|
||||
row['arms'][arm] = dict(metrics=metric, execution=e)
|
||||
rows.append(row)
|
||||
return rows
|
||||
|
||||
|
||||
class GatesTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.reg = registry()
|
||||
self.auth = authority(self.reg)
|
||||
|
||||
def evaluate(self, assay, rows, *, mode='physiological', dan='PAM15', cue=C):
|
||||
kwargs = dict(mode=mode, dan_type=dan, conditioned_cue=cue, registry=self.reg, authority=self.auth)
|
||||
if assay in ('normal', 'delayed'):
|
||||
return g.evaluate_acquisition(rows, assay=assay, **kwargs)
|
||||
return getattr(g, 'evaluate_' + assay)(rows, nodes=NODES, populations=POPS, downstream_policy=g.DOWNSTREAM_POLICY, **kwargs)
|
||||
|
||||
def test_registry_checks_real_seed_collision_and_exact_40_cells(self):
|
||||
for mutation in ('eval_train', 'eval_eval', 'train_train', 'duplicate_cell', '63bit', 'boolseed', 'extra_eval', 'missing_block'):
|
||||
reg = registry()
|
||||
values = list(reg['blocks'].values())
|
||||
if mutation == 'eval_train': values[0]['evaluation_sources'][C]['seed'] = values[1]['training_sources'][0]['seed']
|
||||
if mutation == 'eval_eval': values[1]['evaluation_sources'][C]['seed'] = values[0]['evaluation_sources'][C]['seed']
|
||||
if mutation == 'train_train': values[1]['training_sources'][0]['stream_id'] = values[0]['training_sources'][0]['stream_id']
|
||||
if mutation == 'duplicate_cell': values[1]['replicate'] = values[0]['replicate']
|
||||
if mutation == '63bit': values[0]['training_sources'][0]['seed'] = 2**63
|
||||
if mutation == 'boolseed': values[0]['training_sources'][0]['seed'] = True
|
||||
if mutation == 'extra_eval': values[0]['evaluation_sources']['extra'] = values[0]['evaluation_sources'][C]
|
||||
if mutation == 'missing_block': reg['blocks'].pop(next(iter(reg['blocks'])))
|
||||
with self.subTest(mutation=mutation), self.assertRaises(ValueError):
|
||||
g.validate_registry(reg, expected_sha256=g.descriptor_sha256(reg))
|
||||
self.assertEqual(g.validate_registry(self.reg, expected_sha256=self.auth['registry_sha256'])['blocks'], 40)
|
||||
|
||||
def test_registry_hash_and_population_mutation_rejected(self):
|
||||
self.reg['protocol_sha256'] = sha('other')
|
||||
with self.assertRaisesRegex(ValueError, 'changed'):
|
||||
self.evaluate('reversal', reversal_rows(self.reg))
|
||||
self.reg = registry(); self.auth = authority(self.reg)
|
||||
bad = dict(POPS, nonMBONDownstream=np.array([3, 4], np.int32))
|
||||
with self.assertRaises(ValueError):
|
||||
g.evaluate_reversal(reversal_rows(self.reg), mode='physiological', dan_type='PAM15', conditioned_cue=C,
|
||||
registry=self.reg, authority=self.auth, nodes=NODES, populations=bad, downstream_policy=g.DOWNSTREAM_POLICY)
|
||||
|
||||
def test_all_four_assays_both_signs_reciprocal_cues_and_no_claims(self):
|
||||
for assay, factory in (('normal', acquisition_rows), ('delayed', acquisition_rows), ('reversal', reversal_rows), ('retention', retention_rows)):
|
||||
for dan in g.M.DAN_TYPES:
|
||||
for cue in g.M.CUES:
|
||||
rows = factory(self.reg, dan=dan, cue=cue, **({'assay': assay} if assay in ('normal', 'delayed') else {}))
|
||||
result = self.evaluate(assay, rows, dan=dan, cue=cue)
|
||||
with self.subTest(assay=assay, dan=dan, cue=cue):
|
||||
self.assertTrue(result['predicate_pass'])
|
||||
self.assertEqual(result['successful_same_replicate_conjunctions'], 5)
|
||||
self.assertFalse(result['scientific_learning_pass_claimed'])
|
||||
self.assertFalse(result['external_authority_verified'])
|
||||
self.assertFalse(result['data_backed_claimed'])
|
||||
json.dumps(result, allow_nan=False)
|
||||
|
||||
def test_reversal_zero_is_failure_but_legacy_style_inequality_is_true(self):
|
||||
rows = reversal_rows(self.reg)
|
||||
for row in rows:
|
||||
row['reversal']['states'] = states(C, 1, neutral_strength=1); rebind(row['reversal'])
|
||||
result = self.evaluate('reversal', rows)
|
||||
self.assertFalse(result['predicate_pass'])
|
||||
self.assertTrue(all(row['legacy_style_sign_inequality_on_registered_S'] for row in result['replicates']))
|
||||
|
||||
def test_reversal_old_cue_only_and_mbon_only_cannot_satisfy_new_downstream_gate(self):
|
||||
for only_old_cue in (True, False):
|
||||
rows = reversal_rows(self.reg)
|
||||
for row in rows:
|
||||
if only_old_cue:
|
||||
row['reversal']['states'] = states(C, -1)
|
||||
else:
|
||||
row['reversal']['states'][N] = state(2, downstream=False)
|
||||
rebind(row['reversal'])
|
||||
result = self.evaluate('reversal', rows)
|
||||
self.assertFalse(result['predicate_pass'])
|
||||
if not only_old_cue:
|
||||
change = result['replicates'][0]['acquisition_to_reversal_changes_by_cue'][N]['populations']
|
||||
self.assertTrue(change['legacyDownstream']['events_changed'])
|
||||
self.assertFalse(change['nonMBONDownstream']['events_changed'])
|
||||
|
||||
def test_reversal_same_replicate_conjunction_and_exact_three(self):
|
||||
rows = reversal_rows(self.reg)
|
||||
rows[2]['no_reversal']['states'] = states(C, -1); rebind(rows[2]['no_reversal'])
|
||||
rows[3]['reversal']['states'] = states(C, 1, neutral_strength=1); rebind(rows[3]['reversal'])
|
||||
rows[4]['reversal']['states'][N] = state(2, downstream=False); rebind(rows[4]['reversal'])
|
||||
result = self.evaluate('reversal', rows)
|
||||
self.assertEqual(result['successful_same_replicate_conjunctions'], 2)
|
||||
self.assertFalse(result['predicate_pass'])
|
||||
rows[2] = reversal_rows(self.reg)[2]
|
||||
self.assertTrue(self.evaluate('reversal', rows)['predicate_pass'])
|
||||
|
||||
def test_retention_same_replicate_at_both_times_not_separate_time_majorities(self):
|
||||
rows = retention_rows(self.reg)
|
||||
for index, times in ((2, ('10',)), (3, ('1',)), (4, ('1', '10'))):
|
||||
for second in times:
|
||||
p = rows[index]['checkpoints'][second]['trained']
|
||||
p['states'] = states(); rebind(p)
|
||||
result = self.evaluate('retention', rows)
|
||||
self.assertEqual(result['successful_same_replicate_conjunctions'], 2)
|
||||
self.assertFalse(result['predicate_pass'])
|
||||
rows[2] = retention_rows(self.reg)[2]
|
||||
self.assertTrue(self.evaluate('retention', rows)['predicate_pass'])
|
||||
|
||||
def test_retention_frozen_equality_opposite_sign_and_no_nonmbon_change_fail(self):
|
||||
for variant in ('equal_frozen', 'opposite', 'mbon_only'):
|
||||
rows = retention_rows(self.reg)
|
||||
for row in rows:
|
||||
for second in ('1', '10'):
|
||||
pair_value = row['checkpoints'][second]['trained']
|
||||
if variant == 'equal_frozen':
|
||||
pair_value = row['checkpoints'][second]['frozen']; pair_value['states'] = states(C, 1)
|
||||
elif variant == 'opposite': pair_value['states'] = states(C, -1)
|
||||
else: pair_value['states'] = states(C, 1, downstream=False)
|
||||
rebind(pair_value)
|
||||
self.assertFalse(self.evaluate('retention', rows)['predicate_pass'])
|
||||
|
||||
def test_retention_chain_full_state_clock_and_probe_policy_mutations_rejected(self):
|
||||
for variant in ('clock', 'delta', 'parent', 'queue', 'reset', 'analytic', 'prefix', 'missing_time', 'input', 'feedback', 'newUS', 'short_probe', 'fresh_probe', 'raw_state'):
|
||||
rows = retention_rows(self.reg)
|
||||
execution_value = rows[0]['execution']['trained']
|
||||
cp = execution_value['checkpoints']['10']
|
||||
p = rows[0]['checkpoints']['10']['trained']
|
||||
if variant == 'clock': cp['absolute_tick'] += 1
|
||||
if variant == 'delta': cp['delta_sha256'] = sha('changed')
|
||||
if variant == 'parent': cp['parent_checkpoint_sha256'] = execution_value['source_checkpoint_sha256']
|
||||
if variant == 'queue': cp['carry_sha256'].pop('apl_pending')
|
||||
if variant == 'reset': execution_value['reset_state'] = True
|
||||
if variant == 'analytic': execution_value['analytic_time_advance'] = True
|
||||
if variant == 'prefix': execution_value['one_second_is_prefix_of_ten_second'] = False
|
||||
if variant == 'missing_time': rows[0]['checkpoints'].pop('0')
|
||||
if variant == 'input': p['evaluation_input_sha256'][C] = sha('other')
|
||||
if variant == 'feedback': p['feedback_to_training_or_idle'] = True
|
||||
if variant == 'newUS': p['US_requested'] = True
|
||||
if variant == 'short_probe': p['probe_steps'] = 1000
|
||||
if variant == 'fresh_probe': p['state_policy'] = 'common_frozen_reset'
|
||||
if variant == 'raw_state': p['states'][C]['v'][0] += .001
|
||||
with self.subTest(variant=variant), self.assertRaises(ValueError): self.evaluate('retention', rows)
|
||||
|
||||
def test_reversal_delta_lineage_terminal_inventory_and_receipt_mutations_rejected(self):
|
||||
for variant in ('resetdelta', 'early', 'epochs', 'cue', 'receipt', 'snapshot_receipt', 'probeAB', 'evaldraw', 'wrongcell', 'trainstream'):
|
||||
rows = reversal_rows(self.reg)
|
||||
e = rows[0]['execution']['reversal']
|
||||
if variant == 'resetdelta': e['initial_delta_sha256'] = sha('zero')
|
||||
if variant == 'early': e['terminal_pairings'] = 20
|
||||
if variant == 'epochs': e['completed_epochs'] = 99
|
||||
if variant == 'cue': e['reinforced_cue'] = C
|
||||
if variant == 'receipt': e['receipt_sha256'] = rows[0]['execution']['acquisition']['receipt_sha256']
|
||||
if variant == 'snapshot_receipt': rows[0]['reversal']['receipt_sha256'] = rows[0]['acquisition']['receipt_sha256']
|
||||
if variant == 'probeAB': rows[0]['reversal']['probe_receipt_sha256'][N] = rows[0]['reversal']['probe_receipt_sha256'][C]
|
||||
if variant == 'evaldraw': rows[0]['replicate_unit'] = 'evaluation'
|
||||
if variant == 'wrongcell': rows[1]['replicate_id'] = rows[0]['replicate_id']
|
||||
if variant == 'trainstream': rows[0]['training_stream_ids'] = rows[1]['training_stream_ids']
|
||||
with self.subTest(variant=variant), self.assertRaises(ValueError): self.evaluate('reversal', rows)
|
||||
|
||||
def test_acquisition_controls_and_frozen_gate_are_preserved(self):
|
||||
for variant in ('missing_control', 'delayed_timing', 'metric_mutation', 'population'):
|
||||
rows = acquisition_rows(self.reg, assay='delayed')
|
||||
if variant == 'missing_control': rows[0]['arms'].pop('DAN-only')
|
||||
if variant == 'delayed_timing': rows[0]['arms']['frozen']['execution']['us_tick'] = 900
|
||||
if variant == 'metric_mutation': rows[0]['arms']['paired']['metrics']['rawS'] = 999.
|
||||
if variant == 'population': rows[0]['arms']['paired']['metrics']['cues'][C]['nodes_raw_sha256'] = sha('other')
|
||||
with self.subTest(variant=variant), self.assertRaises(ValueError): self.evaluate('delayed', rows)
|
||||
|
||||
def normal_reports(self):
|
||||
return [self.evaluate('normal', acquisition_rows(self.reg, mode, dan, cue), mode=mode, dan=dan, cue=cue)
|
||||
for mode in g.M.MODES for dan in g.M.DAN_TYPES for cue in g.M.CUES]
|
||||
|
||||
def test_cohort_exact_eight_cells_missing_not_run_and_mutation_rejected(self):
|
||||
reports = self.normal_reports()
|
||||
result = g.summarize_cohort(reports, registry=self.reg, authority=self.auth, required_assays=('normal',))
|
||||
self.assertTrue(result['all_functional_predicates_pass'])
|
||||
self.assertFalse(result['legacy_H_and_integrity_gates_included'])
|
||||
missing = g.summarize_cohort(reports[:-1], registry=self.reg, authority=self.auth, required_assays=('normal',))
|
||||
self.assertIsNone(missing['all_functional_predicates_pass'])
|
||||
self.assertEqual(sum(x['status'] == 'NOT-RUN' for x in missing['table']), 1)
|
||||
for variant in ('duplicate', 'predicate', 'conjunction', 'controlgain', 'unsupportedclaim'):
|
||||
changed = copy.deepcopy(reports)
|
||||
if variant == 'duplicate': changed[-1] = changed[0]
|
||||
if variant == 'predicate': changed[0]['predicate_pass'] = False
|
||||
if variant == 'conjunction': changed[0]['replicates'][0]['conjunction_pass'] = False
|
||||
if variant == 'controlgain': next(iter(changed[0]['legacy_control_MBON_gains'].values()))[changed[0]['replicates'][0]['replicate_id']] = 900.
|
||||
if variant == 'unsupportedclaim': changed[0]['scientific_learning_pass_claimed'] = True
|
||||
with self.subTest(variant=variant), self.assertRaises(ValueError):
|
||||
g.summarize_cohort(changed, registry=self.reg, authority=self.auth, required_assays=('normal',))
|
||||
|
||||
def test_legacy_H_mapping_absent_and_both_DAN_control_sources_explicit(self):
|
||||
reports = self.normal_reports()
|
||||
self.assertEqual(g.legacy_h_cohort_audit(reports, registry=self.reg, authority=self.auth, declared_mapping=None)['status'], 'NOT-TESTABLE')
|
||||
good = g.legacy_h_cohort_audit(reports, registry=self.reg, authority=self.auth, declared_mapping=g.H_MAPPING)
|
||||
self.assertEqual(len(good['groups']), 4)
|
||||
self.assertTrue(good['both_pass'])
|
||||
rows = acquisition_rows(self.reg, dan='PPL103')
|
||||
for row in rows:
|
||||
row['arms']['random reward']['metrics'] = g.M.arm_metrics(states(), states(C, -2), conditioned_cue=C, nodes=NODES, populations=POPS)
|
||||
replacement = self.evaluate('normal', rows, dan='PPL103')
|
||||
reports = [replacement if (x['mode'], x['dan_type'], x['conditioned_cue']) == ('physiological', 'PPL103', C) else x for x in reports]
|
||||
result = g.legacy_h_cohort_audit(reports, registry=self.reg, authority=self.auth, declared_mapping=g.H_MAPPING)
|
||||
group = next(x for x in result['groups'] if x['mode'] == 'physiological' and x['conditioned_cue'] == C)
|
||||
self.assertTrue(group['control_sources']['PAM15']['predicate_pass'])
|
||||
self.assertFalse(group['control_sources']['PPL103']['predicate_pass'])
|
||||
self.assertFalse(result['both_pass'])
|
||||
|
||||
def test_full_cohort_recomputes_followup_predicates_and_keeps_assay_majorities_separate(self):
|
||||
reports = []
|
||||
for mode in g.M.MODES:
|
||||
for dan in g.M.DAN_TYPES:
|
||||
for cue in g.M.CUES:
|
||||
for assay, factory in (('normal', acquisition_rows), ('delayed', acquisition_rows),
|
||||
('reversal', reversal_rows), ('retention', retention_rows)):
|
||||
rows = factory(self.reg, mode, dan, cue, **({'assay': assay} if assay in ('normal', 'delayed') else {}))
|
||||
reports.append(self.evaluate(assay, rows, mode=mode, dan=dan, cue=cue))
|
||||
result = g.summarize_cohort(reports, registry=self.reg, authority=self.auth, required_assays=g.ASSAYS)
|
||||
self.assertEqual(len(result['table']), 32)
|
||||
self.assertTrue(result['all_functional_predicates_pass'])
|
||||
for variant in ('reversal_sign', 'reversal_predicate', 'retention_sign', 'retention_predicate', 'retention_time0'):
|
||||
changed = copy.deepcopy(reports)
|
||||
rev = next(x for x in changed if x['assay'] == 'reversal')['replicates'][0]
|
||||
ret = next(x for x in changed if x['assay'] == 'retention')['replicates'][0]
|
||||
if variant == 'reversal_sign': rev['rawS']['reversal'] = 999.
|
||||
if variant == 'reversal_predicate': rev['predicates']['strict_three_signed_relations'] = False
|
||||
if variant == 'retention_sign': ret['times']['10']['rawS_trained'] = 999.
|
||||
if variant == 'retention_predicate': ret['times']['10']['predicates']['beyond_time_matched_frozen'] = False
|
||||
if variant == 'retention_time0': ret['times']['0']['contributes_to_gate'] = True
|
||||
with self.subTest(variant=variant), self.assertRaises(ValueError):
|
||||
g.summarize_cohort(changed, registry=self.reg, authority=self.auth, required_assays=g.ASSAYS)
|
||||
|
||||
def test_frozen_retention_source_cannot_claim_updated_delta(self):
|
||||
rows = retention_rows(self.reg)
|
||||
rows[0]['execution']['frozen']['source_execution']['initial_delta_sha256'] = sha('another-zero')
|
||||
with self.assertRaisesRegex(ValueError, 'Frozen training'):
|
||||
self.evaluate('retention', rows)
|
||||
|
||||
def test_inputs_not_mutated_and_output_does_not_alias_inputs(self):
|
||||
rows = reversal_rows(self.reg)
|
||||
before = copy.deepcopy(rows)
|
||||
result = self.evaluate('reversal', rows)
|
||||
for old, new in zip(before, rows):
|
||||
for snapshot in ('pre', 'acquisition', 'reversal', 'no_reversal'):
|
||||
for cue in g.M.CUES:
|
||||
for key in g.M.STATE_KEYS:
|
||||
np.testing.assert_array_equal(old[snapshot]['states'][cue][key], new[snapshot]['states'][cue][key])
|
||||
result['replicates'][0]['metrics']['acquisition']['rawS'] = 888.
|
||||
self.assertEqual(self.evaluate('reversal', rows)['replicates'][0]['rawS']['acquisition'], 1.)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -0,0 +1,129 @@
|
||||
"""Pure temporary preparation integration; all old context/Git/biology mocked.
|
||||
|
||||
No historical files, sampling, brain, source-module execution or GPU is used.
|
||||
Real plan/anatomy/complete-source authentication belongs to separate validation.
|
||||
"""
|
||||
import copy
|
||||
import json
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import tempfile
|
||||
from types import SimpleNamespace
|
||||
import unittest
|
||||
from unittest.mock import Mock,patch
|
||||
|
||||
import numpy as np
|
||||
|
||||
import prepare_execution as P
|
||||
|
||||
|
||||
def save(path,value):
|
||||
path.parent.mkdir(parents=True,exist_ok=True);path.write_text(json.dumps(value),encoding='utf-8')
|
||||
|
||||
|
||||
class PrepareFixture:
|
||||
def __init__(self,root):
|
||||
self.root=root;self.model=root/'models/conditioning-execution-v1';self.model.mkdir(parents=True)
|
||||
(self.model/'synthetic.py').write_text('# synthetic source only\n')
|
||||
self.exp=root/'experiments/phase4aq-fixture';self.exp.mkdir(parents=True)
|
||||
self.ap=root/'experiments/phase4ap-fixture';self.ap.mkdir()
|
||||
self.ao=root/'experiments/phase4ao-fixture';self.ao.mkdir()
|
||||
self.checkpoint=self.ap/'runs/D1--reference--epoch-001';self.checkpoint.mkdir(parents=True)
|
||||
save(self.checkpoint/'checkpoint-manifest.json',{'synthetic':True})
|
||||
self.before=root/'before.npz';self.bm=root/'before.json'
|
||||
np.savez_compressed(self.before,edge_id=np.array([0],np.int64),plastic_delta_mv=np.array([0.],np.float32));save(self.bm,{'synthetic':'before'})
|
||||
self.mapping=root/'mapping.npz'
|
||||
np.savez_compressed(self.mapping,edge_id=np.array([0],np.int64),source_neuron_idx=np.array([1],np.int32),
|
||||
target_neuron_idx=np.array([2],np.int32),target_compartment_verbatim=np.array(["y5B'2a"]))
|
||||
self.authority=self.ap/'jobs/D1--reference--epoch-001.authority.json'
|
||||
save(self.authority,dict(checkpoint_dir=str(self.checkpoint),checkpoint_manifest_sha256=P.digest(self.checkpoint/'checkpoint-manifest.json'),
|
||||
files={'candidate_map':P.A.pin(self.mapping),'overlay_before':P.A.pin(self.before),'overlay_manifest_before':P.A.pin(self.bm)}))
|
||||
update=self.ap/'updates/D1--reference--epoch-001';update.mkdir(parents=True)
|
||||
for name in ('chain-receipt.json','update-receipt.json','delta-after.npz','overlay-manifest.json'):(update/name).write_bytes(b'synthetic')
|
||||
save(self.ap/'cases/D1--reference--epoch-001/spec.json',{'synthetic':'pinned-template'})
|
||||
static=self.ao/'inputs/static';static.mkdir(parents=True)
|
||||
self.populations=static/'populations.npz'
|
||||
np.savez_compressed(self.populations,PAM15=np.array([3,4,5,6],np.int32),Kenyon_Cell=np.array([1],np.int32))
|
||||
self.tables={}
|
||||
for cue in ('A','B'):
|
||||
self.tables[cue]={'targets':np.array([10,11],np.int32),'rates_hz':np.array([1.,2.],np.float32)}
|
||||
np.savez_compressed(static/(cue+'-rates.npz'),**self.tables[cue])
|
||||
self.fullplan=self.ao/'protocol/full-trial-plan.json';save(self.fullplan,{'synthetic':'not sampled'})
|
||||
pins={str(p):P.digest(p) for p in (self.before,self.bm,self.mapping,self.populations,self.fullplan)}
|
||||
self.reg=dict(input_sha256=pins,source_sha256={},prepared_file_sha256={},
|
||||
initial_overlay={'overlay_file':str(self.before),'overlay_manifest':str(self.bm)})
|
||||
self.plan=dict(imported_parents={'D1':dict(role='AP.D1.reference.epoch001',checkpoint_manifest=str(self.checkpoint/'checkpoint-manifest.json'),
|
||||
sha256=P.digest(self.checkpoint/'checkpoint-manifest.json'))},initial_overlay={'overlay_file':P.A.pin(self.before),'overlay_manifest':P.A.pin(self.bm)},
|
||||
calls=[{'call_id':'ref','case_group':'shared'},{'call_id':'light','case_group':'shared'}])
|
||||
self.old=SimpleNamespace(C=SimpleNamespace(load_checkpoint=Mock(return_value={'fresh':True,'steps':1200})),
|
||||
helper=lambda:SimpleNamespace(verify_seal=Mock(return_value={'synthetic_verified':True})),
|
||||
previous_integrity=Mock(return_value={'synthetic_old_checksum':True}))
|
||||
self.inputs=SimpleNamespace(load_rate_tables=Mock(return_value={'tables':copy.deepcopy(self.tables),'audit':{'synthetic_no_sampler':True}}))
|
||||
self.mechanical=Mock(return_value=({'tick':np.array([1199],np.int32),'neuron_idx':np.array([1],np.int32)}, {'synthetic':True}))
|
||||
self.planobj=SimpleNamespace(build_plan=lambda:copy.deepcopy(self.plan),validate_plan=Mock(return_value=True),
|
||||
derive_case_spec=lambda template,call_id,**kw:{'steps':1000,'case_group':'shared'},mechanical_requests=self.mechanical)
|
||||
|
||||
def git(self,command):
|
||||
if command[-2:]==['rev-parse','HEAD']:return b'a'*40+b'\n'
|
||||
if command[-2]=='show':return (self.root/command[-1].split(':',1)[1]).read_bytes()
|
||||
raise AssertionError('Unexpected external command')
|
||||
|
||||
def run(self,git=None):
|
||||
with patch.object(P,'ROOT',self.root),patch.object(P,'MODEL',self.model),patch.object(P,'EXP',self.exp), \
|
||||
patch.object(P,'AP',self.ap),patch.object(P,'AO',self.ao),patch.object(P,'PLAN',self.planobj), \
|
||||
patch.object(P,'old_context',return_value=(self.old,self.reg,{})), \
|
||||
patch.object(P.subprocess,'check_output',side_effect=self.git if git is None else git), \
|
||||
patch.object(P.shutil,'disk_usage',return_value=SimpleNamespace(free=100*1024**3)), \
|
||||
patch.dict(sys.modules,{'conditioning_preflight_inputs':self.inputs}):
|
||||
return P.prepare()
|
||||
|
||||
|
||||
class PreparationTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.tmp=tempfile.TemporaryDirectory();self.f=PrepareFixture(Path(self.tmp.name).resolve())
|
||||
def tearDown(self):self.tmp.cleanup()
|
||||
|
||||
def test_exclusive_registration_source_snapshot_and_shared_case(self):
|
||||
sha=self.f.run();reg=P.read(self.f.exp/'protocol/preregistered.json')
|
||||
self.assertEqual(sha,P.digest(self.f.exp/'protocol/preregistered.json'))
|
||||
self.assertEqual(set(reg['case_templates']),{'shared'})
|
||||
self.assertEqual((self.f.exp/'protocol/source-snapshot/synthetic.py').read_bytes(),(self.f.model/'synthetic.py').read_bytes())
|
||||
self.assertFalse(reg['brain_or_sampler_run_during_preparation']);self.assertFalse(reg['future_hashes_fabricated'])
|
||||
self.assertFalse(reg['scientific_acquisition_authorized']);self.assertFalse(reg['learning_success_claimed'])
|
||||
self.f.inputs.load_rate_tables.assert_called_once_with(self.f.root)
|
||||
self.f.old.C.load_checkpoint.assert_called_once_with(self.f.checkpoint,self.f.plan['imported_parents']['D1']['sha256'])
|
||||
with self.assertRaisesRegex(ValueError,'empty experiment'):self.f.run()
|
||||
|
||||
def test_uncommitted_source_blob_rejected_before_new_outputs(self):
|
||||
def mismatch(command):return b'a'*40+b'\n' if command[-2:]==['rev-parse','HEAD'] else b'wrong committed source'
|
||||
with self.assertRaisesRegex(ValueError,'committed blob'):self.f.run(git=mismatch)
|
||||
self.assertEqual(list(self.f.exp.iterdir()),[])
|
||||
|
||||
def test_shared_template_must_be_fully_equal(self):
|
||||
self.f.planobj.derive_case_spec=lambda template,call_id,**kw:{'steps':1000,'wrong_mode_leak':call_id}
|
||||
with self.assertRaisesRegex(ValueError,'Shared comparison case templates differ'):self.f.run()
|
||||
self.assertFalse((self.f.exp/'protocol/preregistered.json').exists())
|
||||
|
||||
def test_pinned_rate_arrays_need_dtype_and_bits_not_json_similarity(self):
|
||||
self.f.inputs.load_rate_tables.return_value['tables']['A']['rates_hz']=self.f.tables['A']['rates_hz'].astype(np.float64)
|
||||
with self.assertRaisesRegex(ValueError,'PN mapping differs'):self.f.run()
|
||||
self.assertFalse((self.f.exp/'protocol/preregistered.json').exists())
|
||||
|
||||
def test_candidate_source_outside_KC_is_not_silently_selected(self):
|
||||
np.savez_compressed(self.f.populations,PAM15=np.array([3,4,5,6],np.int32),Kenyon_Cell=np.array([99],np.int32))
|
||||
self.f.reg['input_sha256'][str(self.f.populations)]=P.digest(self.f.populations)
|
||||
with self.assertRaisesRegex(ValueError,'outside original KC'):self.f.run()
|
||||
|
||||
def test_imported_parent_authority_must_match_selected_checkpoint(self):
|
||||
value=P.read(self.f.authority);value['checkpoint_manifest_sha256']='f'*64;save(self.f.authority,value)
|
||||
with self.assertRaisesRegex(ValueError,'selected parent'):self.f.run()
|
||||
self.assertFalse((self.f.exp/'protocol/preregistered.json').exists())
|
||||
|
||||
def test_no_bytecode_or_nested_source_dirs_in_inventory(self):
|
||||
with patch.object(P,'MODEL',self.f.model):
|
||||
self.assertEqual(len(P.source_inventory()),1)
|
||||
(self.f.model/'__pycache__').mkdir()
|
||||
with self.assertRaisesRegex(ValueError,'source files'):P.source_inventory()
|
||||
|
||||
|
||||
if __name__=='__main__':unittest.main()
|
||||
@@ -0,0 +1,573 @@
|
||||
"""Synthetic CPU admission/state/AST tests only. No GPU or scientific input."""
|
||||
import ast
|
||||
import copy
|
||||
import json
|
||||
from pathlib import Path
|
||||
import tempfile
|
||||
from types import SimpleNamespace, ModuleType
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
import numpy as np
|
||||
|
||||
import updated_continuation as m
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
AJ = ROOT / 'apl-timing-lab-v1/gpu_timing.py'
|
||||
|
||||
|
||||
def save(path, value):
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
path.write_text(json.dumps(value, sort_keys=True, allow_nan=False), encoding='utf-8')
|
||||
|
||||
|
||||
def pin(path):
|
||||
return dict(path=str(path), sha256=m._digest(path))
|
||||
|
||||
|
||||
class ArrayTarget:
|
||||
def __init__(self, a):
|
||||
self.a = np.array(a, copy=True)
|
||||
|
||||
def copy_(self, a):
|
||||
self.a[...] = a
|
||||
|
||||
def any(self):
|
||||
return np.asarray(self.a.any())
|
||||
|
||||
def detach(self):
|
||||
return self
|
||||
|
||||
def cpu(self):
|
||||
return self
|
||||
|
||||
def numpy(self):
|
||||
return self.a
|
||||
|
||||
|
||||
def tiny_parent():
|
||||
parent = dict(global_next_tick=41, state=dict(v=np.array([-.051, -.047], np.float64),
|
||||
g=np.array([-0., .00013], np.float64), ref=np.array([22, 3], np.int32)),
|
||||
terminal=dict(spike_ring=np.zeros((19, 2), np.uint8), next_tick=np.asarray(5, np.int64),
|
||||
apl_pending=np.arange(36, dtype=np.float32).reshape(18, 2), apl_state=np.array([.5, 1.], np.float32)))
|
||||
parent['terminal']['spike_ring'][4, 1] = 1
|
||||
return parent
|
||||
|
||||
|
||||
class RuntimeTests(unittest.TestCase):
|
||||
def runtime(self):
|
||||
obj = object.__new__(m.UpdatedRuntime)
|
||||
obj.parent, obj.installations, obj.restorations = tiny_parent(), 1, 0
|
||||
obj.authority = {'value': {'expected_effective_weight_after_sha256': 'a'*64}}
|
||||
obj.torch = SimpleNamespace(float64=np.float64, float32=np.float32, int32=np.int32, uint8=np.uint8)
|
||||
return obj
|
||||
|
||||
def targets(self):
|
||||
state = [ArrayTarget(np.zeros(2, dtype)) for dtype in (np.float64, np.float64, np.int32, np.int32)]
|
||||
return [*state, ArrayTarget(np.zeros((19, 2), np.uint8)), ArrayTarget(np.zeros((18, 2), np.float32)),
|
||||
SimpleNamespace(state=ArrayTarget(np.zeros(2, np.float32))), lambda a, dtype: np.array(a, dtype=dtype)]
|
||||
|
||||
def test_restore_all_bytes_and_no_retroactive_g_rescale(self):
|
||||
obj, args = self.runtime(), self.targets()
|
||||
before = {name:a.tobytes() for name,a in obj.parent['state'].items()}
|
||||
obj.restore(*args)
|
||||
self.assertEqual(args[1].a.tobytes(), before['g'])
|
||||
self.assertEqual(args[0].a.tobytes(), before['v'])
|
||||
self.assertEqual(args[2].a.tobytes(), before['ref'])
|
||||
self.assertFalse(args[3].a.any())
|
||||
self.assertTrue(m._same(args[4].a, m.C.rotate_spike_ring(obj.parent['terminal']['spike_ring'], 5)))
|
||||
self.assertTrue(m._same(args[5].a, obj.parent['terminal']['apl_pending']))
|
||||
self.assertTrue(m._same(args[6].state.a, obj.parent['terminal']['apl_state']))
|
||||
self.assertFalse(obj.restore_audit['existing_g_rescaled'])
|
||||
self.assertTrue(obj.restore_audit['pending_spike_arrivals_use_current_installed_weight'])
|
||||
self.assertEqual(before, {name:a.tobytes() for name,a in obj.parent['state'].items()})
|
||||
with self.assertRaisesRegex(ValueError, 'once'):
|
||||
obj.restore(*args)
|
||||
|
||||
def test_restore_rejects_nonzero_counts_or_before_installation(self):
|
||||
obj, args = self.runtime(), self.targets()
|
||||
obj.installations = 0
|
||||
with self.assertRaises(ValueError): obj.restore(*args)
|
||||
obj.installations = 1
|
||||
args[3].a[0] = 1
|
||||
with self.assertRaisesRegex(ValueError, 'counts'): obj.restore(*args)
|
||||
|
||||
def test_copy_corruption_is_not_hidden_by_receipt(self):
|
||||
obj, args = self.runtime(), self.targets()
|
||||
args[1].copy_ = lambda value: args[1].a.fill(0.)
|
||||
with self.assertRaisesRegex(ValueError, 'state bytes: g'): obj.restore(*args)
|
||||
|
||||
def test_authorized_new_hash_not_parent_old_hash_and_no_double_install(self):
|
||||
obj = self.runtime(); obj.installations = 0
|
||||
def synthetic_original_install(target, *args, **kwargs):
|
||||
target.installations += 1
|
||||
target.effective_sha = 'a'*64
|
||||
obj.parent['summary'] = {'effective_weights_raw_sha256':'b'*64}
|
||||
with patch.object(m.R._Runtime, 'install', synthetic_original_install):
|
||||
obj.install(None)
|
||||
self.assertEqual(obj.installations, 1)
|
||||
with self.assertRaisesRegex(ValueError, 'Double'): obj.install(None)
|
||||
obj.installations = 0
|
||||
obj.authority['value']['expected_effective_weight_after_sha256'] = 'c'*64
|
||||
with patch.object(m.R._Runtime, 'install', synthetic_original_install):
|
||||
with self.assertRaisesRegex(ValueError, 'authorized after'): obj.install(None)
|
||||
|
||||
def test_actual_source_AST_keeps_only_frozen_restore_and_admission(self):
|
||||
for mode in ('reference', 'light'):
|
||||
aj = ModuleType('synthetic_aj'); aj.__file__ = str(AJ)
|
||||
old = dict(aj.__dict__)
|
||||
runtime = SimpleNamespace(write_json=lambda *_:None, audit_sequence=lambda *_:None)
|
||||
function, audit = m.compile_updated(aj, runtime, mode)
|
||||
self.assertTrue(audit['full_AST_rollback_identical'])
|
||||
self.assertTrue(audit['kernels_sorting_and_local_ring_math_unchanged'])
|
||||
self.assertEqual(old, aj.__dict__)
|
||||
self.assertIs(function.__globals__['_runtime'], runtime)
|
||||
self.assertIs(function.__globals__['_continuation'], runtime)
|
||||
self.assertEqual(function.__globals__['__file__'], str(Path(m.__file__).resolve()))
|
||||
|
||||
def test_pending_source_uses_new_weight_and_old_APL_sample(self):
|
||||
# Independent numerical toy: a source emitted before boundary arrives
|
||||
# afterwards; no captured edge weight is stored in the source ring.
|
||||
for cut in (5, 17, 18, 19, 20, 41):
|
||||
source_tick = cut - 1
|
||||
ring = np.zeros((19, 2), np.uint8); ring[source_tick % 19, 0] = 1
|
||||
child = m.C.rotate_spike_ring(ring, cut)
|
||||
g = np.float64(.00013)
|
||||
delta = np.float32(-.00275)
|
||||
base = np.float64(.000275)
|
||||
after = np.add(base, np.multiply(np.float64(delta), np.float64(.001)))
|
||||
arrived = []
|
||||
for tick in range(19):
|
||||
child[tick % 19] = 0
|
||||
if cut+tick >= 18 and child[(tick-18) % 19, 0]:
|
||||
g = np.add(g, after); arrived.append(tick)
|
||||
self.assertEqual(arrived, [17])
|
||||
self.assertEqual(g.tobytes(), np.add(np.float64(.00013), after).tobytes())
|
||||
self.assertNotEqual(g.tobytes(), np.add(np.float64(.00013), base).tobytes())
|
||||
initial = np.arange(36, dtype=np.float32).reshape(18, 2)
|
||||
generated = np.ones((5, 2), np.float32)
|
||||
joined = np.concatenate((initial, generated))
|
||||
self.assertTrue(m.C.audit_carried_sequence(generated, joined[:5], joined[5:], initial)['pass_all'])
|
||||
source = (ROOT/'author-runtime-lab-v1/author_ext.cu').read_text()
|
||||
self.assertIn('weights[edges[j]]', source)
|
||||
|
||||
|
||||
class AdmissionFixture:
|
||||
"""Private tiny input scaffolding. Actual production loaders are mocked."""
|
||||
def __init__(self, root):
|
||||
self.root=root; self.case=root/'case'; self.case.mkdir()
|
||||
self.parentdir=root/'parent'; self.parentdir.mkdir()
|
||||
self.graph=root/'graph'; self.graph.mkdir(); self.apl=root/'apl'; self.apl.mkdir()
|
||||
self.coeff=root/'coeff.json'; save(self.coeff, {})
|
||||
for name in m.GRAPH_FILES: (self.graph/name).write_bytes(b'synthetic graph '+name.encode())
|
||||
for name in m.APL_FILES: (self.apl/name).write_bytes(b'synthetic apl '+name.encode())
|
||||
self.before=root/'before.npz'; self.before.write_bytes(b'before snapshot')
|
||||
self.bm=root/'before.json'; save(self.bm, {'synthetic':True})
|
||||
self.after=root/'after.npz'; self.after.write_bytes(b'after snapshot')
|
||||
self.am=root/'after.json'; save(self.am, {'synthetic':False})
|
||||
(self.parentdir/'overlay-input.npz').write_bytes(self.before.read_bytes())
|
||||
(self.parentdir/'overlay-manifest.json').write_bytes(self.bm.read_bytes())
|
||||
save(self.parentdir/m.MANIFEST, {'synthetic':True})
|
||||
self.parentpin=m._digest(self.parentdir/m.MANIFEST)
|
||||
self.spec=dict(steps=5,max_steps=5,dt_ms=.1,duration_ms=.5,apl_delay_steps=18,
|
||||
record_history=False,within_trial_weight_updates=False,model={'fixed':1},apl={'fixed':2},
|
||||
graph_dir=str(self.graph),apl_bundle_dir=str(self.apl),coefficients_path=str(self.coeff),
|
||||
parent_checkpoint_manifest_sha256=self.parentpin,global_tick_offset=41)
|
||||
save(self.case/'spec.json',self.spec)
|
||||
np.savez_compressed(self.case/'requests.npz',tick=np.empty(0,np.int32),neuron_idx=np.empty(0,np.int32))
|
||||
lab=ROOT/'olfactory-conditioning-lab-v1'
|
||||
self.sources={name:lab/(name.removesuffix('_source')+'.py') for name in m.SOURCE_PINS}
|
||||
self.sources['phase4j_source']=ROOT/'models/male-cns-lif/phase4j.py'
|
||||
if not self.sources['phase4j_source'].exists(): self.sources['phase4j_source']=ROOT/'mb-physiology-v1/phase4j.py'
|
||||
self.sources['am_overlay_source']=ROOT/'wholebrain-plastic-interface-v1/overlay.py'
|
||||
self.sources['eligibility_bridge_source']=ROOT/'wholebrain-plastic-interface-v1/eligibility_bridge.py'
|
||||
self.sources['updated_continuation_source']=Path(m.__file__).resolve()
|
||||
self.sources['cpu_validator_source']=Path(m.__file__).resolve().parent/'validate_update_cpu.py'
|
||||
frozen={str(p):m._digest(p) for p in [*(self.graph/n for n in m.GRAPH_FILES),*(self.apl/n for n in m.APL_FILES),self.coeff]}
|
||||
frozen.update({str((ROOT/relative).resolve()):sha for relative,sha in m.R.PINS.items()})
|
||||
self.value=dict(schema=m.SCHEMA,boundary_id='synthetic',registration_sha256='a'*64,
|
||||
transition='epoch_update',diagnostic_mode='light',input_policy='empty_idle',
|
||||
case={'spec':pin(self.case/'spec.json'),'requests':pin(self.case/'requests.npz')},
|
||||
parent={'directory':str(self.parentdir),'checkpoint_manifest_sha256':self.parentpin},global_tick_offset=41,
|
||||
overlay_before={'file':pin(self.before),'manifest':pin(self.bm)},overlay_after={'file':pin(self.after),'manifest':pin(self.am)},
|
||||
expected_effective_weight_before_sha256='b'*64,expected_effective_weight_after_sha256='c'*64,
|
||||
update=None,cpu_validation=None,source_files={k:pin(p) for k,p in self.sources.items()},frozen_inputs=frozen)
|
||||
self.path=root/'authority.json'; self.refresh()
|
||||
self.plan={'edge_id':np.array([1],np.int64),'plastic_delta_mv':np.array([0],np.float32),'base_candidate_mv':np.array([.275],np.float32)}
|
||||
self.meta=dict(mask_path=str(root/'mask.npy'),mask_sha256='m'*64,base_candidate_path=str(root/'base.npy'),
|
||||
base_candidate_sha256='d'*64,aj_model_dir=str(ROOT/'apl-timing-lab-v1'),
|
||||
am_overlay_path=str(self.sources['am_overlay_source']),am_overlay_sha256=m.R.AM_OVERLAY_SHA)
|
||||
self.parent=dict(fresh=True,global_tick_offset=0,global_next_tick=41,steps=41,directory=self.parentdir,
|
||||
manifest_sha256=self.parentpin,manifest={'schema':'phase4an-checkpoint-v1'},
|
||||
summary={'effective_weights_raw_sha256':'b'*64,'input_sha256':{'coefficients.json':m._digest(self.coeff),'base_weights.npy':m._digest(self.graph/'weights.npy')}},
|
||||
overlay={'delta_raw_sha256':m.R._raw(self.plan['plastic_delta_mv'])},ancestry_directories=[self.parentdir])
|
||||
self.helper=object()
|
||||
|
||||
def refresh(self): save(self.path,self.value)
|
||||
|
||||
def admit(self, effective=None):
|
||||
with patch.object(m,'load_checkpoint',return_value=self.parent), patch.object(m.C,'_parent_spec',return_value=self.spec), \
|
||||
patch.object(m.R,'load_overlay',return_value=(self.helper,self.plan,self.meta,{})), \
|
||||
patch.object(m,'_expected_effective',side_effect=['b'*64,'c'*64] if effective is None else effective), \
|
||||
patch.object(m,'_epoch_update',return_value={'pass_all':True}) as ep:
|
||||
result=m.validate_authority(self.path,m._digest(self.path))
|
||||
return result,ep.call_count
|
||||
|
||||
|
||||
class AdmissionTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.tmp=tempfile.TemporaryDirectory(); self.f=AdmissionFixture(Path(self.tmp.name).resolve())
|
||||
def tearDown(self): self.tmp.cleanup()
|
||||
|
||||
def test_all_actual_frozen_sources_and_return_contract(self):
|
||||
result,calls=self.f.admit()
|
||||
self.assertEqual(calls,1)
|
||||
for key in ('value','authority','authority_sha256','paths','pins','parent','case_dir','spec','helper',
|
||||
'sources','before_plan','after_plan','before_meta','after_meta'):
|
||||
self.assertIn(key,result)
|
||||
self.assertEqual(result['update_root_authority_sha256'],m._digest(self.f.path))
|
||||
self.assertNotIn('torch',result)
|
||||
|
||||
def test_wrong_absolute_clock_and_wrong_case_parent(self):
|
||||
for field,new in (('global_tick_offset',40),('parent_checkpoint_manifest_sha256','f'*64)):
|
||||
with self.subTest(field=field):
|
||||
original=copy.deepcopy(self.f.spec)
|
||||
self.f.spec[field]=new;save(self.f.case/'spec.json',self.f.spec)
|
||||
self.f.value['case']['spec']=pin(self.f.case/'spec.json');self.f.refresh()
|
||||
with self.assertRaisesRegex(ValueError,'Case parent/clock'):self.f.admit()
|
||||
self.f.spec=original;save(self.f.case/'spec.json',original)
|
||||
self.f.value['case']['spec']=pin(self.f.case/'spec.json');self.f.refresh()
|
||||
self.f.value['global_tick_offset']=42;self.f.refresh()
|
||||
with self.assertRaisesRegex(ValueError,'absolute continuation clock'):self.f.admit()
|
||||
|
||||
def test_second_update_is_rejected(self):
|
||||
self.f.parent['fresh']=False
|
||||
with self.assertRaisesRegex(ValueError,'only once'):self.f.admit()
|
||||
|
||||
def test_authority_hash_and_actual_before_copy_not_self_asserted(self):
|
||||
with self.assertRaisesRegex(ValueError,'changed'):
|
||||
m.validate_authority(self.f.path,'e'*64)
|
||||
(self.f.parentdir/'overlay-input.npz').write_bytes(b'wrong bytes')
|
||||
with self.assertRaisesRegex(ValueError,'Before snapshot'):self.f.admit()
|
||||
|
||||
def test_empty_idle_rejects_requests_probe_does_not_claim_semantics(self):
|
||||
np.savez_compressed(self.f.case/'requests.npz',tick=np.array([0],np.int32),neuron_idx=np.array([1],np.int32))
|
||||
self.f.value['case']['requests']=pin(self.f.case/'requests.npz');self.f.refresh()
|
||||
with self.assertRaisesRegex(ValueError,'empty_idle'):self.f.admit()
|
||||
self.f.value['input_policy']='externally_pinned_CS_probe';self.f.refresh()
|
||||
self.assertEqual(self.f.admit()[0]['value']['input_policy'],'externally_pinned_CS_probe')
|
||||
|
||||
def test_extra_fields_or_source_replacement_fail(self):
|
||||
self.f.value['trust_me']=True;self.f.refresh()
|
||||
with self.assertRaisesRegex(ValueError,'schema'):self.f.admit()
|
||||
del self.f.value['trust_me']
|
||||
self.f.value['source_files']['conditioning_update_source']['sha256']='f'*64;self.f.refresh()
|
||||
with self.assertRaisesRegex(ValueError,'Frozen source'):self.f.admit()
|
||||
|
||||
def test_missing_compiled_pin_not_accepted(self):
|
||||
del self.f.value['frozen_inputs'][str((ROOT/'author-runtime-lab-v1/author_ext.cu').resolve())];self.f.refresh()
|
||||
with self.assertRaisesRegex(ValueError,'dependency authority'):self.f.admit()
|
||||
|
||||
def test_identical_CPU_validator_copy_is_not_the_actual_executor_path(self):
|
||||
copied=self.f.root/'validator-copy.py'
|
||||
copied.write_bytes(self.f.sources['cpu_validator_source'].read_bytes())
|
||||
self.f.value['source_files']['cpu_validator_source']=pin(copied);self.f.refresh()
|
||||
with self.assertRaisesRegex(ValueError,'validator source path'):self.f.admit()
|
||||
|
||||
def idle(self):
|
||||
self.f.value.update(transition='idle',update=None,cpu_validation=None,
|
||||
expected_effective_weight_after_sha256='b'*64,overlay_after=copy.deepcopy(self.f.value['overlay_before']))
|
||||
self.f.parent.update(fresh=False,manifest={'schema':m.CHECKPOINT_SCHEMA},input_policy='empty_idle',
|
||||
update_root_authority_sha256='e'*64)
|
||||
self.f.refresh()
|
||||
|
||||
def test_idle_retains_original_update_root_no_E_or_cpu_recompute(self):
|
||||
self.idle()
|
||||
result,calls=self.f.admit(['b'*64,'b'*64])
|
||||
self.assertEqual(calls,0)
|
||||
self.assertEqual(result['update_root_authority_sha256'],'e'*64)
|
||||
self.assertIsNone(result['paths']['epoch_authority'])
|
||||
self.assertIsNone(result['paths']['cpu_validation'])
|
||||
|
||||
def test_probe_parent_cannot_flow_back_into_idle_or_another_probe(self):
|
||||
self.idle();self.f.parent['input_policy']='externally_pinned_CS_probe'
|
||||
for policy in ('empty_idle','externally_pinned_CS_probe'):
|
||||
self.f.value['input_policy']=policy;self.f.refresh()
|
||||
with self.assertRaisesRegex(ValueError,'probe branch'):self.f.admit(['b'*64,'b'*64])
|
||||
|
||||
def test_idle_cannot_authorize_a_second_snapshot_change(self):
|
||||
self.idle()
|
||||
self.f.value['overlay_after']={'file':pin(self.f.after),'manifest':pin(self.f.am)};self.f.refresh()
|
||||
with self.assertRaisesRegex(ValueError,'Idle changed'):self.f.admit(['b'*64,'b'*64])
|
||||
self.idle();self.f.value['update']={};self.f.refresh()
|
||||
with self.assertRaisesRegex(ValueError,'no new update'):self.f.admit(['b'*64,'b'*64])
|
||||
|
||||
def test_wrong_expected_weight_hash(self):
|
||||
self.f.value['expected_effective_weight_after_sha256']='e'*64;self.f.refresh()
|
||||
with self.assertRaisesRegex(ValueError,'After effective'):self.f.admit()
|
||||
|
||||
def test_output_and_build_reject_entire_ancestry_before_Torch(self):
|
||||
admitted,_=self.f.admit()
|
||||
ancestor=self.f.root/'ancestor';ancestor.mkdir()
|
||||
admitted['parent']['ancestry_directories'].append(ancestor)
|
||||
for output,build in ((ancestor/'out',self.f.root/'build'),(self.f.root/'out',ancestor/'build')):
|
||||
with patch.object(m,'validate_authority',return_value=admitted),patch.object(m.R,'_load') as loader:
|
||||
with self.assertRaises(ValueError):m.run(self.f.path,m._digest(self.f.path),output,build)
|
||||
loader.assert_not_called()
|
||||
self.assertFalse(output.exists());self.assertFalse(build.exists())
|
||||
|
||||
def test_dtype_sorting_and_request_schema_reject(self):
|
||||
for ticks,nodes in ((np.array([0],np.int64),np.array([1],np.int32)),
|
||||
(np.array([1,0],np.int32),np.array([1,1],np.int32)),
|
||||
(np.array([5],np.int32),np.array([1],np.int32))):
|
||||
np.savez_compressed(self.f.case/'requests.npz',tick=ticks,neuron_idx=nodes)
|
||||
with self.assertRaises(ValueError):m._requests(self.f.case/'requests.npz',self.f.spec,'externally_pinned_CS_probe')
|
||||
|
||||
|
||||
class CheckpointDispatchTests(unittest.TestCase):
|
||||
def test_old_checkpoint_is_honestly_dispatched_to_old_C(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
root=Path(tmp);save(root/m.MANIFEST,{'schema':'phase4an-checkpoint-v1'})
|
||||
with patch.object(m.C,'load_checkpoint',return_value={'fresh':True}) as old:
|
||||
self.assertEqual(m.load_checkpoint(root,m._digest(root/m.MANIFEST)),{'fresh':True})
|
||||
old.assert_called_once()
|
||||
|
||||
def test_new_checkpoint_cannot_copy_old_provenance(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
root=Path(tmp)
|
||||
save(root/'runtime-provenance.json',{'schema':'phase4an-continuation-runtime-v1','complete':True})
|
||||
with self.assertRaisesRegex(ValueError,'genuine new'):m._record(root,{root})
|
||||
|
||||
def test_new_checkpoint_cycle_and_wrong_external_pin(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
root=Path(tmp).resolve();save(root/m.MANIFEST,{'schema':m.CHECKPOINT_SCHEMA})
|
||||
with self.assertRaisesRegex(ValueError,'External checkpoint'):m.load_checkpoint(root,'e'*64)
|
||||
with self.assertRaisesRegex(ValueError,'cycle'):m.load_checkpoint(root,m._digest(root/m.MANIFEST),_seen={root})
|
||||
|
||||
|
||||
class NewCheckpointFixture:
|
||||
def __init__(self, f):
|
||||
self.f=f;self.admitted,_=f.admit();self.out=f.root/'new-output';self.out.mkdir()
|
||||
self.parent=self.admitted['parent'];self.parent.update(tiny_parent())
|
||||
self.state=dict(step=np.array([0],np.int32),neuron_idx=np.array([1],np.int32),counts=np.array([0,1],np.int32),
|
||||
v=np.array([-.05,-.052],np.float64),g=np.array([0.,-.003],np.float64),ref=np.array([0,18],np.int32))
|
||||
# Production APL dimensions, tiny canonical neural dimension only in tests.
|
||||
self.parent['terminal']['apl_pending']=np.zeros((18,4064),np.float32)
|
||||
self.parent['terminal']['apl_pending'][1,0]=np.float32(.5)
|
||||
ring=m.C.rotate_spike_ring(self.parent['terminal']['spike_ring'],5)
|
||||
for tick in range(5):ring[tick]=0
|
||||
ring[0,1]=1
|
||||
self.terminal=dict(spike_ring=ring,apl_pending=np.zeros((18,4064),np.float32),
|
||||
apl_state=np.array([1.,2.],np.float32),next_tick=np.asarray(5,np.int64))
|
||||
np.savez_compressed(self.out/'state.npz',**self.state)
|
||||
np.savez_compressed(self.out/'terminal-queues.npz',**self.terminal)
|
||||
np.save(self.out/'apl-pending-tail.float32.npy',self.terminal['apl_pending'])
|
||||
save(self.out/'apl-timing-audit.json',dict(pending_raw_sha256=m.R._raw(self.terminal['apl_pending']),
|
||||
apl_delay_steps=18,brain_tail_advanced=False,final_apl_state_u32_bits=self.terminal['apl_state'].view(np.uint32).tolist(),
|
||||
global_tick_offset=41,global_next_tick=46,initial_queue_raw_sha256=m.R._raw(self.parent['terminal']['apl_pending'])))
|
||||
self.summary=dict(complete=True,pass_all=True,all_finite=True,steps=5,completed_ticks=5,nodes=2,edges=6,
|
||||
precision='float64',apl_precision='float32',within_trial_weight_updates=False,checkpoint_continuation_used=True,
|
||||
global_tick_offset=41,global_next_tick=46,explicit_steps_executed=5,max_steps=5,hidden_early_stop=False,
|
||||
entire_neural_trial_executed=True,record_history=False,counts_scope='segment_only_not_lifetime',event_tick_scope='segment_local',
|
||||
weight_update_at_boundary_authorized=True,frozen_same_weight_retention_claimed=False,
|
||||
parent_checkpoint_manifest_sha256=self.parent['manifest_sha256'],diagnostic_mode='light',
|
||||
boundary_authority_sha256=self.admitted['authority_sha256'],update_root_authority_sha256=self.admitted['update_root_authority_sha256'],
|
||||
updated_boundary_schema=m.SCHEMA,boundary_transition='epoch_update',input_policy='empty_idle',effective_weights_raw_sha256='c'*64,
|
||||
input_sha256={'spec.json':m._digest(f.case/'spec.json'),'requests.npz':m._digest(f.case/'requests.npz'),
|
||||
'base_weights.npy':m._digest(f.graph/'weights.npy'),'coefficients.json':m._digest(f.coeff)})
|
||||
save(self.out/'summary.json',self.summary)
|
||||
save(self.out/'finite-audit.json',dict(all_finite=True,first_failure_tick=-1,finite_observed_ticks=5))
|
||||
save(self.out/'overlay-audit.json',dict(complete=True,weights_updated_during_run=False,effective_weights_raw_sha256='c'*64,
|
||||
delta_raw_sha256=m.R._raw(f.plan['plastic_delta_mv']),mask_sha256=m.R.MASK_SHA,am_helper_sha256=m.R.AM_OVERLAY_SHA))
|
||||
(self.out/'overlay-input.npz').write_bytes(f.after.read_bytes())
|
||||
(self.out/'overlay-manifest.json').write_bytes(f.am.read_bytes())
|
||||
_,audit=m.C.derive_continued(AJ.read_bytes(),'light')
|
||||
self.provenance=dict(schema=m.PROVENANCE_SCHEMA,complete=True,mode='light',source_file=str(Path(m.__file__).resolve()),
|
||||
source_sha256=m._digest(m.__file__),authority_file=str(f.path),authority_sha256=self.admitted['authority_sha256'],ast=audit,
|
||||
input_sha256=self.admitted['pins'],old_globals_patched=False,weights_updated_during_run=False,U_recomputed_here=False,
|
||||
learning_pass_claimed=False,parent_checkpoint_manifest_sha256=f.parentpin,global_tick_offset=41,global_next_tick=46,
|
||||
external_CPU_validation_receipt_bound=True,external_registration_process_and_probe_semantics_verified_here=False)
|
||||
restored=dict(v=self.parent['state']['v'],g=self.parent['state']['g'],ref=self.parent['state']['ref'],
|
||||
spike_ring=m.C.rotate_spike_ring(self.parent['terminal']['spike_ring'],5),apl_pending=self.parent['terminal']['apl_pending'],
|
||||
apl_state=self.parent['terminal']['apl_state'])
|
||||
save(self.out/'boundary-restore-audit.json',dict(restored_raw_sha256={k:m.R._raw(a) for k,a in restored.items()},
|
||||
all_state_and_queue_bytes_exact=True,existing_g_rescaled=False,retroactive_arrival_reweighting=False,
|
||||
pending_spike_arrivals_use_current_installed_weight=True,pending_APL_samples_preserved=True,
|
||||
boundary_installations=1,restorations=1,learning_pass_claimed=False))
|
||||
self.receipt=dict(schema='conditioning-updated-receipt-v1',complete=True,authority_file=str(f.path),
|
||||
authority_sha256=self.admitted['authority_sha256'],parent_checkpoint_dir=str(f.parentdir),parent_checkpoint_manifest_sha256=f.parentpin,
|
||||
global_tick_offset=41,global_next_tick=46,segment_steps=5,update_root_authority_sha256=self.admitted['update_root_authority_sha256'],
|
||||
input_policy='empty_idle',weights_updated_during_run=False,counts_scope='segment_only_not_lifetime',
|
||||
checkpoint_continuation_verified_by_GPU_comparison=False,learning_pass_claimed=False)
|
||||
self.rebind()
|
||||
|
||||
def rebind(self):
|
||||
for key,name in (('summary_sha256','summary.json'),('finite_audit_sha256','finite-audit.json'),
|
||||
('terminal_queues_sha256','terminal-queues.npz'),('overlay_audit_sha256','overlay-audit.json'),('state_sha256','state.npz')):
|
||||
self.provenance[key]=m._digest(self.out/name)
|
||||
save(self.out/'runtime-provenance.json',self.provenance)
|
||||
payload=m.C._tree_hashes(self.out);payload.pop(m.RECEIPT,None)
|
||||
self.receipt['payload_sha256']=payload;save(self.out/m.RECEIPT,self.receipt)
|
||||
|
||||
def record(self):
|
||||
with patch.object(m,'validate_authority',return_value=self.admitted),patch.object(m.C,'N',2),patch.object(m.C,'E',6):
|
||||
return m._record(self.out,{self.out})
|
||||
|
||||
|
||||
class NewCheckpointTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.tmp=tempfile.TemporaryDirectory();self.f=NewCheckpointFixture(AdmissionFixture(Path(self.tmp.name).resolve()))
|
||||
def tearDown(self):self.tmp.cleanup()
|
||||
|
||||
def test_full_payload_exclusive_seal_round_trip(self):
|
||||
self.assertEqual(self.f.record()['global_next_tick'],46)
|
||||
with patch.object(m,'validate_authority',return_value=self.f.admitted),patch.object(m.C,'N',2),patch.object(m.C,'E',6):
|
||||
sealed=m.seal_checkpoint(self.f.out)
|
||||
loaded=m.load_checkpoint(self.f.out,sealed['sha256'])
|
||||
self.assertEqual(loaded['manifest']['schema'],m.CHECKPOINT_SCHEMA)
|
||||
self.assertTrue(m._same(loaded['state']['g'],self.f.state['g']))
|
||||
self.assertFalse(loaded['manifest']['checkpoint_continuation_verified_by_GPU_comparison'])
|
||||
with self.assertRaisesRegex(ValueError,'already sealed'):m.seal_checkpoint(self.f.out)
|
||||
(self.f.out/'extra.json').write_text('{}')
|
||||
with self.assertRaisesRegex(ValueError,'inventory'):m.load_checkpoint(self.f.out,sealed['sha256'])
|
||||
|
||||
def test_rehashed_wrong_parent_and_clock_still_rejected(self):
|
||||
self.f.provenance['parent_checkpoint_manifest_sha256']='f'*64;self.f.rebind()
|
||||
with self.assertRaisesRegex(ValueError,'boundary/clock'):self.f.record()
|
||||
self.f.provenance['parent_checkpoint_manifest_sha256']=self.f.f.parentpin
|
||||
self.f.summary['global_next_tick']=47;save(self.f.out/'summary.json',self.f.summary);self.f.rebind()
|
||||
with self.assertRaisesRegex(ValueError,'global_next_tick'):self.f.record()
|
||||
|
||||
def test_rehashed_changed_unconsumed_queue_rejected(self):
|
||||
self.f.terminal['spike_ring'][18,0]^=np.uint8(1)
|
||||
np.savez_compressed(self.f.out/'terminal-queues.npz',**self.f.terminal);self.f.rebind()
|
||||
with self.assertRaisesRegex(ValueError,'Unwritten carried'):self.f.record()
|
||||
|
||||
def test_rehashed_restoration_g_receipt_not_trusted(self):
|
||||
path=self.f.out/'boundary-restore-audit.json';value=m.R._read_json(path)
|
||||
value['restored_raw_sha256']['g']='f'*64;save(path,value);self.f.rebind()
|
||||
with self.assertRaisesRegex(ValueError,'Boundary restore'):self.f.record()
|
||||
|
||||
def test_actual_state_dtype_rejected_after_rehash(self):
|
||||
self.f.state['g']=self.f.state['g'].astype(np.float32)
|
||||
np.savez_compressed(self.f.out/'state.npz',**self.f.state);self.f.rebind()
|
||||
with self.assertRaisesRegex(ValueError,'parent g'):self.f.record()
|
||||
|
||||
|
||||
class EpochChainFixture:
|
||||
"""Full candidate cardinality and actual metadata bindings; no U execution.
|
||||
|
||||
Q is mocked explicitly: its frozen pure arithmetic has separate tests.
|
||||
This fixture exercises E/CPU file chain and supplied full-array authority.
|
||||
"""
|
||||
def __init__(self,root):
|
||||
self.f=AdmissionFixture(root);f=self.f
|
||||
self.update=root/'postprocess';self.update.mkdir()
|
||||
self.before={'edge_id':np.arange(14232,dtype=np.int64),'plastic_delta_mv':np.zeros(14232,np.float32),
|
||||
'base_candidate_mv':np.full(14232,.275,np.float32)}
|
||||
self.after={k:a.copy() for k,a in self.before.items()};self.after['plastic_delta_mv'][0]=np.float32(-.00275)
|
||||
kc=np.arange(4064,dtype=np.int32);source=(np.arange(14232)%4064).astype(np.int32);target=np.full(14232,4500,np.int32)
|
||||
comp=np.full(14232,"y5B'2a")
|
||||
np.save(f.apl/'kc_globals.npy',kc);np.save(root/'kc.npy',kc);np.save(root/'mask.npy',self.before['edge_id'])
|
||||
np.save(root/'base.npy',self.before['base_candidate_mv']);np.save(f.graph/'src.npy',source);np.save(f.graph/'dst.npy',target)
|
||||
np.savez_compressed(root/'map.npz',edge_id=self.before['edge_id'],source_neuron_idx=source,target_neuron_idx=target,target_compartment_verbatim=comp)
|
||||
np.savez_compressed(f.before,edge_id=self.before['edge_id'],plastic_delta_mv=self.before['plastic_delta_mv'])
|
||||
self.bm={**f.meta,'mask_sha256':m._digest(root/'mask.npy'),'base_candidate_sha256':m._digest(root/'base.npy')}
|
||||
save(f.bm,self.bm)
|
||||
self.afterfile=self.update/'delta-after.npz';np.savez_compressed(self.afterfile,edge_id=self.after['edge_id'],plastic_delta_mv=self.after['plastic_delta_mv'])
|
||||
self.am={**self.bm,'parent_snapshot_sha256':m._digest(f.before)};save(self.update/'overlay-manifest.json',self.am)
|
||||
self.state=dict(step=np.array([0],np.int32),neuron_idx=np.array([0],np.int32),counts=np.array([1],np.int32),
|
||||
v=np.array([-.05]),g=np.array([.001]),ref=np.array([18],np.int32))
|
||||
np.savez_compressed(f.parentdir/'state.npz',**self.state)
|
||||
self.parent=dict(fresh=True,global_tick_offset=0,steps=4,directory=f.parentdir,manifest_sha256=f.parentpin,state=self.state,
|
||||
summary={'diagnostic_mode':'light','effective_weights_raw_sha256':'b'*64},
|
||||
manifest={'files_sha256':{'state.npz':m._digest(f.parentdir/'state.npz')}},provenance={'input_sha256':{}})
|
||||
self.epaths=dict(spec=f.case/'spec.json',requests=f.case/'requests.npz',overlay_before=f.before,overlay_manifest_before=f.bm,
|
||||
state=f.parentdir/'state.npz',kc=root/'kc.npy',canonical_kc=f.apl/'kc_globals.npy',candidate_map=root/'map.npz',
|
||||
mask=root/'mask.npy',base_candidate=root/'base.npy',**{key:f.sources[key] for key in m.E_SOURCE_ROLES})
|
||||
self.epath=root/'epoch-authority.json'
|
||||
frozen={str(p):m._digest(p) for p in [*(f.graph/n for n in m.GRAPH_FILES),*(f.apl/n for n in m.APL_FILES),f.coeff]}
|
||||
frozen.update({str((ROOT/relative).resolve()):sha for relative,sha in m.R.PINS.items()})
|
||||
command=dict(steps=4,compartment="y5B'2a",us_tick=3,d_command=1.,frozen=False,trace_backend='numpy')
|
||||
self.evalue=dict(schema='phase4an-epoch-postprocess-authority-v1',epoch_id='synthetic-e0',diagnostic_mode='light',command=command,
|
||||
checkpoint_dir=str(f.parentdir),checkpoint_manifest_sha256=f.parentpin,files={role:pin(path) for role,path in self.epaths.items()},frozen_inputs=frozen)
|
||||
save(self.epath,self.evalue)
|
||||
self.epins={str(self.epath):m._digest(self.epath),str(f.parentdir/m.MANIFEST):f.parentpin,
|
||||
**{str(p):m._digest(p) for p in self.epaths.values()},**frozen}
|
||||
self.parent['provenance']['input_sha256']={str(self.epaths[k]):m._digest(self.epaths[k]) for k in ('spec','requests','overlay_before','overlay_manifest_before')}
|
||||
arrays=dict(step=self.state['step'],neuron_idx=self.state['neuron_idx'],kc=kc,candidate_edge_id=self.before['edge_id'],
|
||||
candidate_sources=source,candidate_targets=target,candidate_compartments=comp,delta_before=self.before['plastic_delta_mv'],base_candidate=self.before['base_candidate_mv'])
|
||||
self.receipt=dict(input_arrays={k:m._evidence(a) for k,a in arrays.items()},command=dict(steps=4,n_neurons=5000,
|
||||
compartment="y5B'2a",us_tick=3,D_scheduled=1.,frozen=False,trace_backend='numpy'),payload_sha256='d'*64)
|
||||
save(self.update/'update-receipt.json',self.receipt)
|
||||
self.chain=dict(schema='phase4an-epoch-postprocess-chain-v1',complete=True,epoch_id='synthetic-e0',authority_file=str(self.epath),
|
||||
authority_sha256=m._digest(self.epath),coordinator_source_sha256=m.SOURCE_PINS['conditioning_epoch_source'],command=command,
|
||||
diagnostic_mode='light',source_neural_checkpoint_dir=str(f.parentdir),source_neural_checkpoint_manifest_sha256=f.parentpin,
|
||||
before_overlay_file_sha256=m._digest(f.before),before_overlay_manifest_sha256=m._digest(f.bm),
|
||||
after_overlay_file_sha256=m._digest(self.afterfile),after_overlay_manifest_sha256=m._digest(self.update/'overlay-manifest.json'),
|
||||
source_state_file_sha256=m._digest(self.epaths['state']),source_spec_sha256=m._digest(self.epaths['spec']),
|
||||
source_requests_sha256=m._digest(self.epaths['requests']),input_files_sha256=self.epins,
|
||||
output_files_sha256={name:m._digest(self.update/name) for name in m.UPDATE_FILES if name!='chain-receipt.json'},
|
||||
runtime_delta_before_raw_sha256=m.R._raw(self.before['plastic_delta_mv']),runtime_effective_weights_raw_sha256='b'*64,
|
||||
update_receipt_payload_sha256='d'*64,runtime_learned_manifest_loader_verified=True,input_and_checkpoint_bytes_reverified=True,
|
||||
candidate_endpoints_equal_graph=True,KC_equals_supplied_canonical_membership=True,weights_installed=False,
|
||||
brain_executed=False,learning_pass_claimed=False,candidate_generated=False)
|
||||
save(self.update/'chain-receipt.json',self.chain)
|
||||
self.paths=dict(before_overlay=f.before,before_manifest=f.bm,after_overlay=self.afterfile,after_manifest=self.update/'overlay-manifest.json')
|
||||
self.value=dict(update={'epoch_authority':pin(self.epath),'files':{name:pin(self.update/name) for name in m.UPDATE_FILES}})
|
||||
self.cp=root/'cpu-validation.json'
|
||||
self.cpu=dict(schema='conditioning-update-cpu-validation-v1',complete=True,epoch_authority_sha256=m._digest(self.epath),
|
||||
parent_checkpoint_manifest_sha256=f.parentpin,update_files_sha256={name:m._digest(self.update/name) for name in m.UPDATE_FILES},
|
||||
before_overlay_sha256=m._digest(f.before),before_manifest_sha256=m._digest(f.bm),after_overlay_sha256=m._digest(self.afterfile),
|
||||
after_manifest_sha256=m._digest(self.update/'overlay-manifest.json'),before_delta_raw_sha256=m.R._raw(self.before['plastic_delta_mv']),
|
||||
after_delta_raw_sha256=m.R._raw(self.after['plastic_delta_mv']),update_receipt_payload_sha256='d'*64,
|
||||
validator_source=pin(f.sources['cpu_validator_source']),frozen_U_source_sha256=m.SOURCE_PINS['conditioning_update_source'],
|
||||
frozen_U_verify_receipt_recomputed=True,actual_sealed_events_used=True,full_candidate_mapping_verified=True,
|
||||
brain_executed=False,learning_pass_claimed=False)
|
||||
save(self.cp,self.cpu);self.value['cpu_validation']=pin(self.cp)
|
||||
|
||||
def run(self):
|
||||
pins={str(p):m._digest(p) for p in [*self.paths.values(),*self.f.sources.values()]}
|
||||
with patch.object(m,'_Q',return_value=SimpleNamespace(audit_delta_binding=lambda *a,**k:{'pass_all':True})), \
|
||||
patch.object(m.C,'_parent_spec',return_value=self.f.spec),patch.object(m.C,'N',5000):
|
||||
return m._epoch_update(self.value,self.paths,self.f.sources,pins,self.parent,self.before,self.after,self.bm,self.am)
|
||||
|
||||
|
||||
class EpochChainTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.tmp=tempfile.TemporaryDirectory();self.f=EpochChainFixture(Path(self.tmp.name).resolve())
|
||||
def tearDown(self):self.tmp.cleanup()
|
||||
|
||||
def test_full_four_files_actual_inputs_and_cpu_schema_bind(self):
|
||||
self.assertTrue(self.f.run()['pass_all'])
|
||||
|
||||
def test_chain_wrong_parent_rehashed_still_rejected(self):
|
||||
self.f.chain['source_neural_checkpoint_manifest_sha256']='e'*64
|
||||
save(self.f.update/'chain-receipt.json',self.f.chain)
|
||||
self.f.value['update']['files']['chain-receipt.json']=pin(self.f.update/'chain-receipt.json')
|
||||
with self.assertRaisesRegex(ValueError,'Original E chain'):self.f.run()
|
||||
|
||||
def test_cpu_no_recomputation_or_wrong_after_raw_rejected(self):
|
||||
for key,value in (('frozen_U_verify_receipt_recomputed',False),('after_delta_raw_sha256','e'*64)):
|
||||
original=copy.deepcopy(self.f.cpu);self.f.cpu[key]=value;save(self.f.cp,self.f.cpu)
|
||||
self.f.value['cpu_validation']=pin(self.f.cp)
|
||||
with self.assertRaisesRegex(ValueError,'CPU recomputation'):self.f.run()
|
||||
self.f.cpu=original
|
||||
|
||||
def test_update_four_file_hash_changed_or_extra_file(self):
|
||||
(self.f.update/'extra.json').write_text('{}')
|
||||
with self.assertRaisesRegex(ValueError,'four-file'):self.f.run()
|
||||
|
||||
def test_actual_array_not_receipt_booleans_is_checked(self):
|
||||
self.f.parent['state']['step'][0]=1
|
||||
with self.assertRaisesRegex(ValueError,'actual array binding'):self.f.run()
|
||||
|
||||
def test_candidate_endpoint_change_rejected_even_with_same_shape(self):
|
||||
mapping=m.C._npz(self.f.epaths['candidate_map'],('edge_id','source_neuron_idx','target_neuron_idx','target_compartment_verbatim'))
|
||||
mapping['source_neuron_idx'][0]=22
|
||||
np.savez_compressed(self.f.epaths['candidate_map'],**mapping)
|
||||
with self.assertRaisesRegex(ValueError,'changed'):self.f.run()
|
||||
|
||||
|
||||
if __name__=='__main__':unittest.main()
|
||||
@@ -0,0 +1,68 @@
|
||||
"""CPU-only chain/mutation/real-source loading tests; no production events."""
|
||||
import copy
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
import numpy as np
|
||||
import validate_update_cpu as V
|
||||
|
||||
|
||||
class ValidationTests(unittest.TestCase):
|
||||
def fixture(self):
|
||||
parent=Path('/synthetic/parent');auth={'epoch_id':'one','command':{'fixture':True},
|
||||
'diagnostic_mode':'reference','checkpoint_manifest_sha256':'2'*64}
|
||||
roles=('state','spec','requests','overlay_before','overlay_manifest_before')
|
||||
paths={r:Path('/synthetic/'+r) for r in roles};pins={p:str(i+3)*64 for i,p in enumerate(paths.values())}
|
||||
hashes={name:format(i+8,'x')*64 for i,name in enumerate(V.FILES)}
|
||||
chain=dict(schema='phase4an-epoch-postprocess-chain-v1',complete=True,
|
||||
weights_installed=False,brain_executed=False,learning_pass_claimed=False,candidate_generated=False,
|
||||
coordinator_source_sha256=V.E_SHA,authority_sha256='1'*64,epoch_id='one',command=auth['command'],
|
||||
diagnostic_mode='reference',source_neural_checkpoint_dir=str(parent),
|
||||
source_neural_checkpoint_manifest_sha256='2'*64,input_files_sha256={str(p):v for p,v in pins.items()},
|
||||
output_files_sha256={n:s for n,s in hashes.items() if n!='chain-receipt.json'},
|
||||
after_overlay_file_sha256=hashes['delta-after.npz'],after_overlay_manifest_sha256=hashes['overlay-manifest.json'])
|
||||
for field,role in (('source_state_file_sha256','state'),('source_spec_sha256','spec'),
|
||||
('source_requests_sha256','requests'),('before_overlay_file_sha256','overlay_before'),
|
||||
('before_overlay_manifest_sha256','overlay_manifest_before')):chain[field]=pins[paths[role]]
|
||||
return chain,auth,'1'*64,pins,paths,parent,hashes
|
||||
|
||||
def test_exact_chain(self):V.chain_binding(*self.fixture())
|
||||
|
||||
def test_wrong_parent_command_or_payload_rejected(self):
|
||||
for field,value in (('source_neural_checkpoint_dir','elsewhere'),('source_neural_checkpoint_manifest_sha256','0'*64),
|
||||
('authority_sha256','0'*64),('command',{}),('before_overlay_file_sha256','0'*64),('source_state_file_sha256','0'*64),
|
||||
('after_overlay_file_sha256','0'*64),('output_files_sha256',{}),('input_files_sha256',{}),('complete',False),
|
||||
('weights_installed',True),('learning_pass_claimed',True),('coordinator_source_sha256','0'*64)):
|
||||
args=list(self.fixture());args[0]=copy.deepcopy(args[0]);args[0][field]=value
|
||||
with self.subTest(field=field),self.assertRaises(ValueError):V.chain_binding(*args)
|
||||
|
||||
def test_bit_identity_includes_signed_zero(self):
|
||||
self.assertTrue(V.same(np.zeros(2,np.float32),np.zeros(2,np.float32)))
|
||||
self.assertFalse(V.same(np.zeros(2,np.float32),np.zeros(2,np.float64)))
|
||||
self.assertFalse(V.same(np.array([0.],np.float32),np.array([-0.],np.float32)))
|
||||
|
||||
def test_source_substitution_rejected_before_exec(self):
|
||||
with tempfile.TemporaryDirectory() as d:
|
||||
p=Path(d)/'fake.py';p.write_text('raise RuntimeError("should not execute")')
|
||||
with self.assertRaisesRegex(ValueError,'Unverified source'):V.load('_fixture_not_loaded',p,'0'*64)
|
||||
self.assertNotIn('_fixture_not_loaded',sys.modules)
|
||||
|
||||
def test_actual_frozen_sources_load_without_torch_or_ordinary_R(self):
|
||||
code="""
|
||||
import sys
|
||||
sys.path.insert(0,sys.argv[1]);import validate_update_cpu as V
|
||||
e=V.load('_v_cpu_test_E',V.LAB/'conditioning_epoch.py',V.E_SHA)
|
||||
V.load('engineering_compare',V.LAB/'engineering_compare.py',V.CMP_SHA)
|
||||
q=V.load('_v_cpu_test_Q',V.LAB/'conditioning_preflight_compare.py',V.Q_SHA)
|
||||
assert 'torch' not in sys.modules and 'runtime_light' not in sys.modules
|
||||
assert callable(e._authority) and callable(q.audit_delta_binding)
|
||||
print('ACTUAL_SOURCE_IMPORT_OK')
|
||||
"""
|
||||
result=subprocess.run([sys.executable,'-B','-c',code,str(Path(V.__file__).parent)],text=True,capture_output=True)
|
||||
self.assertEqual(result.returncode,0,result.stderr);self.assertIn('ACTUAL_SOURCE_IMPORT_OK',result.stdout)
|
||||
|
||||
|
||||
if __name__=='__main__':unittest.main()
|
||||
@@ -0,0 +1,601 @@
|
||||
"""Externally authorized, single-update same-state continuation; not learning proof.
|
||||
|
||||
Only epoch_update from a sealed fresh AN checkpoint and its original E four-file
|
||||
postprocess is admitted. Later idle transitions retain the installed snapshot.
|
||||
The input policy is empty_idle or externally_pinned_CS_probe. Probe CS/seed/no-US
|
||||
semantics and branch lineage belong to the registered coordinator, not this module.
|
||||
E/U are NEVER imported/executed here. An external CPU validation receipt binds U's
|
||||
recomputation; its executor/process/registration authority belongs to the caller.
|
||||
No public small-graph mode. CPU synthetic tests exercise private pure helpers.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import importlib.util
|
||||
import json
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
||||
SOURCE_PINS = {
|
||||
'runtime_continuation_source': '0b8e8e0a6a23a079dc62a88355ce355d53b3ae22f6665519a8f6aef2dcfc5aba',
|
||||
'runtime_light_source': '522b8c31ea938890fe15364fccd25ccc5bded54101754909f255532e7ad01aae',
|
||||
'conditioning_epoch_source': '757935a4815d9f625640df685184ed3fe44a8845323562796da7aa43cbb194e1',
|
||||
'conditioning_update_source': '96efff678cff910654eb08e86f1a17789e4e5589e340345f419c7027a7d547e2',
|
||||
'conditioning_preflight_compare_source': 'b88fd9a88d9f92d5c4d042b90f2129b015e8d4bd810c41351ee573241e2d4c2e',
|
||||
'engineering_compare_source': '5a2403f11bc08d65a9d242ac2cf9686b850e0c3680d65659f785e9b6b50c0238',
|
||||
'eligibility_bridge_source': '174fb8d14619189e74b095e77a6db18b14c93046dc431c0b55710a5aa2dd2e61',
|
||||
'phase4j_source': 'abb4574da85f00bd9ef61024c65993ef81d42651ff8d8d63c15dd69c6222471e',
|
||||
'am_overlay_source': '7f891d0ba79b393c96e75fd2dee2eddc51e57d8213eaac2779703bc2c18712b4',
|
||||
}
|
||||
SCHEMA = 'conditioning-updated-boundary-v1'
|
||||
CHECKPOINT_SCHEMA = 'conditioning-updated-checkpoint-v1'
|
||||
PROVENANCE_SCHEMA = 'conditioning-updated-runtime-v1'
|
||||
RECEIPT = 'updated-continuation-receipt.json'
|
||||
MANIFEST = 'checkpoint-manifest.json'
|
||||
GRAPH_FILES = ('nodes.npy', 'edge_id.npy', 'src.npy', 'dst.npy', 'signed_raw.npy', 'ptr.npy', 'weights.npy')
|
||||
APL_FILES = ('input_matrix.npy', 'output_matrix.npy', 'kc_globals.npy', 'apl_globals.npy')
|
||||
UPDATE_FILES = ('chain-receipt.json', 'update-receipt.json', 'delta-after.npz', 'overlay-manifest.json')
|
||||
E_SOURCE_ROLES = ('runtime_light_source', 'runtime_continuation_source', 'conditioning_update_source',
|
||||
'eligibility_bridge_source', 'phase4j_source', 'am_overlay_source')
|
||||
E_ROLES = frozenset(('spec', 'requests', 'overlay_before', 'overlay_manifest_before', 'state', 'kc',
|
||||
'canonical_kc', 'candidate_map', 'mask', 'base_candidate', *E_SOURCE_ROLES))
|
||||
|
||||
|
||||
def _require(ok, message):
|
||||
if not ok:
|
||||
raise ValueError(message)
|
||||
|
||||
|
||||
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 _continuation():
|
||||
path = Path(__file__).resolve().parent.parent / 'olfactory-conditioning-lab-v1/runtime_continuation.py'
|
||||
raw = path.read_bytes()
|
||||
expected = SOURCE_PINS['runtime_continuation_source']
|
||||
_require(hashlib.sha256(raw).hexdigest() == expected, 'Frozen C source pin changed')
|
||||
name = 'conditioning_updated_pinned_C'
|
||||
existing = sys.modules.get(name)
|
||||
if existing is not None:
|
||||
_require(getattr(existing, '__updated_pin__', None) == expected and
|
||||
Path(existing.__file__).resolve() == path, 'C module identity collision')
|
||||
return existing
|
||||
spec = importlib.util.spec_from_file_location(name, path)
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
sys.modules[name] = module
|
||||
try:
|
||||
exec(compile(raw, str(path), 'exec'), module.__dict__)
|
||||
except BaseException:
|
||||
sys.modules.pop(name, None)
|
||||
raise
|
||||
module.__updated_pin__ = expected
|
||||
return module
|
||||
|
||||
|
||||
C = _continuation()
|
||||
R = C.R # The ONLY runtime/helper cache owner. Never import ordinary R or E.
|
||||
|
||||
|
||||
def _canonical(value):
|
||||
return json.dumps(value, sort_keys=True, separators=(',', ':'), ensure_ascii=False, allow_nan=False)
|
||||
|
||||
|
||||
def _same(a, b):
|
||||
return a.dtype == b.dtype and a.shape == b.shape and a.tobytes() == b.tobytes()
|
||||
|
||||
|
||||
def _entry(entry, pins):
|
||||
R.require(type(entry) is dict and set(entry) == {'path', 'sha256'} and R._sha(entry['sha256']), 'Malformed file pin')
|
||||
raw = Path(entry['path'])
|
||||
R.require(raw.is_absolute() and raw.is_file() and not raw.is_symlink(), 'Expected absolute regular unlinked file')
|
||||
path = raw.resolve(strict=True)
|
||||
R.require(str(path) not in pins or pins[str(path)] == entry['sha256'], 'Conflicting file pins')
|
||||
pins[str(path)] = entry['sha256']
|
||||
return path
|
||||
|
||||
|
||||
def _check(pins):
|
||||
for path, sha in pins.items():
|
||||
R.require(R._sha(sha) and _digest(path) == sha, 'Source/input changed: ' + str(path))
|
||||
|
||||
|
||||
def _evidence(value):
|
||||
return dict(dtype=value.dtype.str, shape=list(value.shape), nbytes=int(value.nbytes),
|
||||
raw_c_order_sha256=R._raw(value))
|
||||
|
||||
|
||||
def _Q(sources):
|
||||
R._load('engineering_compare', sources['engineering_compare_source'], SOURCE_PINS['engineering_compare_source'])
|
||||
return R._load('conditioning_updated_pinned_Q', sources['conditioning_preflight_compare_source'],
|
||||
SOURCE_PINS['conditioning_preflight_compare_source'])
|
||||
|
||||
|
||||
def _requests(path, spec, policy):
|
||||
values = C._npz(path, ('tick', 'neuron_idx'))
|
||||
tick, node = values['tick'], values['neuron_idx']
|
||||
R.require(tick.dtype == node.dtype == np.int32 and tick.ndim == node.ndim == 1 and tick.shape == node.shape,
|
||||
'Invalid request dtype/shape')
|
||||
R.require(np.all((tick >= 0) & (tick < spec['steps'])) and np.all((node >= 0) & (node < C.N)), 'Request outside case')
|
||||
keys = tick.astype(np.int64) * C.N + node
|
||||
R.require(len(keys) < 2 or np.all(keys[1:] > keys[:-1]), 'Requests must be sorted unique')
|
||||
R.require(policy in ('empty_idle', 'externally_pinned_CS_probe'), 'Invalid input policy')
|
||||
R.require(policy != 'empty_idle' or len(tick) == 0, 'empty_idle contains requests')
|
||||
return values
|
||||
|
||||
|
||||
def _expected_effective(helper, plan, spec):
|
||||
maps = {}
|
||||
try:
|
||||
graph = Path(spec['graph_dir'])
|
||||
for name, dtype, size in (('nodes', 'int32', C.N), ('edge_id', 'int64', C.E),
|
||||
('src', 'int32', C.E), ('weights', 'float64', C.E)):
|
||||
a = np.load(graph / (name + '.npy'), mmap_mode='r', allow_pickle=False)
|
||||
maps[name] = a
|
||||
R.require(a.dtype == np.dtype(dtype) and a.shape == (size,), 'Full graph dtype/shape changed: ' + name)
|
||||
R.require(np.array_equal(maps['nodes'], np.arange(C.N, dtype=np.int32)), 'Noncanonical node order')
|
||||
apl = np.load(Path(spec['apl_bundle_dir']) / 'apl_globals.npy', allow_pickle=False)
|
||||
R.require(apl.dtype == np.int32 and apl.shape == (2,), 'Invalid APL IDs')
|
||||
apl_mask = np.isin(maps['src'], apl)
|
||||
R.require(int(apl_mask.sum()) == 5845, 'APL output mask changed')
|
||||
mapping = helper.map_installation(maps['weights'], maps['edge_id'], apl_mask, plan)
|
||||
R.require(mapping['missing_candidate_count'] == 0 and mapping['mapped_candidate_count'] == 14232, 'Full candidate mapping required')
|
||||
return helper.expected_hashes(maps['weights'], apl_mask, mapping)[1]
|
||||
finally:
|
||||
for a in maps.values():
|
||||
a._mmap.close()
|
||||
|
||||
|
||||
def _epoch_update(value, paths, sources, pins, parent, before, after, before_meta, after_meta):
|
||||
update = value['update']
|
||||
R.require(type(update) is dict and set(update) == {'epoch_authority', 'files'}, 'Missing epoch update authority')
|
||||
ep = _entry(update['epoch_authority'], pins)
|
||||
paths['epoch_authority'] = ep
|
||||
R.require(type(update['files']) is dict and set(update['files']) == set(UPDATE_FILES), 'All four original E outputs required')
|
||||
files = {name: _entry(update['files'][name], pins) for name in UPDATE_FILES}
|
||||
directory = files['chain-receipt.json'].parent
|
||||
R.require(all(path == directory / name for name, path in files.items()) and
|
||||
{p.name for p in directory.iterdir()} == set(UPDATE_FILES), 'E output must be exact four-file directory')
|
||||
R.require(files['delta-after.npz'] == paths['after_overlay'] and files['overlay-manifest.json'] == paths['after_manifest'],
|
||||
'Installed after snapshot is not the original E output')
|
||||
_check(pins)
|
||||
authority = R._read_json(ep)
|
||||
R.require(type(authority) is dict and set(authority) == {'schema', 'epoch_id', 'diagnostic_mode', 'command',
|
||||
'checkpoint_dir', 'checkpoint_manifest_sha256', 'files', 'frozen_inputs'} and
|
||||
authority['schema'] == 'phase4an-epoch-postprocess-authority-v1', 'Original E authority schema changed')
|
||||
R.require(parent['fresh'] is True and parent['global_tick_offset'] == 0 and
|
||||
Path(authority['checkpoint_dir']).resolve(strict=True) == parent['directory'] and
|
||||
authority['checkpoint_manifest_sha256'] == parent['manifest_sha256'] and
|
||||
authority['diagnostic_mode'] == parent['summary']['diagnostic_mode'], 'Wrong fresh E parent')
|
||||
R.require(type(authority['files']) is dict and set(authority['files']) == E_ROLES, 'Incomplete E file roles')
|
||||
epins = {str(ep): pins[str(ep)], str(parent['directory'] / MANIFEST): parent['manifest_sha256']}
|
||||
epaths = {role: _entry(entry, epins) for role, entry in authority['files'].items()}
|
||||
for role in E_SOURCE_ROLES:
|
||||
R.require(epins[str(epaths[role])] == SOURCE_PINS[role] and epaths[role] == sources[role], 'E source role mismatch: ' + role)
|
||||
R.require(type(authority['frozen_inputs']) is dict and authority['frozen_inputs'], 'Missing E frozen input pins')
|
||||
for path, sha in authority['frozen_inputs'].items():
|
||||
_entry(dict(path=path, sha256=sha), epins)
|
||||
R.require(epaths['state'] == parent['directory'] / 'state.npz' and
|
||||
parent['manifest']['files_sha256']['state.npz'] == epins[str(epaths['state'])], 'E state is not sealed parent')
|
||||
for role, actual in (('overlay_before', paths['before_overlay']), ('overlay_manifest_before', paths['before_manifest'])):
|
||||
R.require(epaths[role] == actual, 'E before overlay path differs')
|
||||
for role in ('spec', 'requests', 'overlay_before', 'overlay_manifest_before'):
|
||||
R.require(parent['provenance']['input_sha256'].get(str(epaths[role])) == epins[str(epaths[role])], 'E/runtime input differs: ' + role)
|
||||
for path, sha in epins.items():
|
||||
_entry(dict(path=path, sha256=sha), pins)
|
||||
_check(pins)
|
||||
chain = R._read_json(files['chain-receipt.json'])
|
||||
receipt = R._read_json(files['update-receipt.json'])
|
||||
command = authority['command']
|
||||
R.require(type(command) is dict and set(command) == {'steps', 'compartment', 'us_tick', 'd_command', 'frozen', 'trace_backend'}, 'E command schema')
|
||||
R.require(type(command['steps']) is int and command['steps'] == parent['steps'], 'E command clock mismatch')
|
||||
R.require(type(command['d_command']) in (int, float) and command['d_command'] in (0, 1) and
|
||||
type(command['frozen']) is bool and command['trace_backend'] in ('numpy', 'torch') and
|
||||
command['compartment'] in ("B2B'2a", 'a1', "y2a'1", "y5B'2a") and
|
||||
(command['us_tick'] is None or (type(command['us_tick']) is int and 0 <= command['us_tick'] < command['steps'])) and
|
||||
(command['us_tick'] is not None or command['d_command'] == 0), 'E command value/type mismatch')
|
||||
required_chain = dict(schema='phase4an-epoch-postprocess-chain-v1', complete=True,
|
||||
epoch_id=authority['epoch_id'], authority_file=str(ep), authority_sha256=pins[str(ep)],
|
||||
coordinator_source_sha256=SOURCE_PINS['conditioning_epoch_source'], command=command,
|
||||
diagnostic_mode=authority['diagnostic_mode'], source_neural_checkpoint_dir=str(parent['directory']),
|
||||
source_neural_checkpoint_manifest_sha256=parent['manifest_sha256'],
|
||||
before_overlay_file_sha256=pins[str(paths['before_overlay'])],
|
||||
before_overlay_manifest_sha256=pins[str(paths['before_manifest'])],
|
||||
after_overlay_file_sha256=pins[str(paths['after_overlay'])],
|
||||
after_overlay_manifest_sha256=pins[str(paths['after_manifest'])],
|
||||
source_state_file_sha256=epins[str(epaths['state'])], source_spec_sha256=epins[str(epaths['spec'])],
|
||||
source_requests_sha256=epins[str(epaths['requests'])], input_files_sha256=epins,
|
||||
output_files_sha256={name: pins[str(files[name])] for name in UPDATE_FILES if name != 'chain-receipt.json'},
|
||||
runtime_delta_before_raw_sha256=R._raw(before['plastic_delta_mv']),
|
||||
runtime_effective_weights_raw_sha256=parent['summary']['effective_weights_raw_sha256'],
|
||||
update_receipt_payload_sha256=receipt.get('payload_sha256'), runtime_learned_manifest_loader_verified=True,
|
||||
input_and_checkpoint_bytes_reverified=True, candidate_endpoints_equal_graph=True,
|
||||
KC_equals_supplied_canonical_membership=True, weights_installed=False, brain_executed=False,
|
||||
learning_pass_claimed=False, candidate_generated=False)
|
||||
R.require(all(_canonical(chain.get(k)) == _canonical(v) for k, v in required_chain.items()), 'Original E chain mismatch')
|
||||
for role, prefix in (('mask', 'mask'), ('base_candidate', 'base_candidate'), ('am_overlay_source', 'am_overlay')):
|
||||
R.require(Path(before_meta[prefix + '_path']).resolve() == epaths[role] and
|
||||
before_meta[prefix + '_sha256'] == epins[str(epaths[role])], 'E mapping/base authority mismatch')
|
||||
mapping = C._npz(epaths['candidate_map'], ('edge_id', 'source_neuron_idx', 'target_neuron_idx', 'target_compartment_verbatim'))
|
||||
kc = np.load(epaths['kc'], allow_pickle=False)
|
||||
canonical_kc = np.load(epaths['canonical_kc'], allow_pickle=False)
|
||||
base = np.load(epaths['base_candidate'], allow_pickle=False)
|
||||
R.require(epaths['canonical_kc'] == Path(C._parent_spec(parent)['apl_bundle_dir']).resolve() / 'kc_globals.npy' and
|
||||
kc.dtype == np.int32 and kc.shape == (4064,) and _same(kc, canonical_kc), 'Full canonical KC mismatch')
|
||||
R.require(_same(mapping['edge_id'], before['edge_id']) and _same(after['edge_id'], before['edge_id']) and
|
||||
_same(base, before['base_candidate_mv']) and _same(base, after['base_candidate_mv']), 'Full before/after mask/base mismatch')
|
||||
graph = Path(C._parent_spec(parent)['graph_dir'])
|
||||
parent_spec = C._parent_spec(parent)
|
||||
required_epins = [graph / name for name in GRAPH_FILES] + [Path(parent_spec['apl_bundle_dir']) / name for name in APL_FILES]
|
||||
required_epins.append(Path(parent_spec['coefficients_path']))
|
||||
required_epins.extend(Path(before_meta['aj_model_dir']).parent / name for name in R.PINS)
|
||||
R.require(all(str(path.resolve(strict=True)) in authority['frozen_inputs'] for path in required_epins),
|
||||
'Original E authority omitted frozen graph/APL/compiled sources')
|
||||
for role, filename in (('source_neuron_idx', 'src.npy'), ('target_neuron_idx', 'dst.npy')):
|
||||
a = np.load(graph / filename, mmap_mode='r', allow_pickle=False)
|
||||
try:
|
||||
R.require(mapping[role].dtype == np.int32 and mapping[role].shape == (14232,) and
|
||||
_same(mapping[role], a[before['edge_id']]), 'Actual candidate endpoint mismatch')
|
||||
finally:
|
||||
a._mmap.close()
|
||||
compartments = mapping['target_compartment_verbatim']
|
||||
R.require(compartments.dtype.kind == 'U' and compartments.shape == (14232,), 'Invalid full compartment metadata')
|
||||
arrays = dict(step=parent['state']['step'], neuron_idx=parent['state']['neuron_idx'], kc=kc,
|
||||
candidate_edge_id=before['edge_id'], candidate_sources=mapping['source_neuron_idx'],
|
||||
candidate_targets=mapping['target_neuron_idx'], candidate_compartments=compartments,
|
||||
delta_before=before['plastic_delta_mv'], base_candidate=base)
|
||||
R.require(_canonical(receipt.get('input_arrays')) == _canonical({k: _evidence(a) for k, a in arrays.items()}), 'U receipt actual array binding failed')
|
||||
expected_command = dict(steps=command['steps'], n_neurons=C.N, compartment=command['compartment'],
|
||||
us_tick=command['us_tick'], D_scheduled=float(command['d_command']), frozen=command['frozen'], trace_backend=command['trace_backend'])
|
||||
R.require(_canonical(receipt.get('command')) == _canonical(expected_command), 'U receipt command differs')
|
||||
binding = _Q(sources).audit_delta_binding(before['plastic_delta_mv'], after['plastic_delta_mv'], after['plastic_delta_mv'],
|
||||
update_receipt=receipt, parent_snapshot_sha256=pins[str(paths['before_overlay'])], child_manifest=after_meta)
|
||||
R.require(binding['pass_all'] is True, 'Q actual before/after delta binding failed')
|
||||
cp = _entry(value['cpu_validation'], pins)
|
||||
paths['cpu_validation'] = cp
|
||||
cpu = R._read_json(cp)
|
||||
expected_cpu = dict(schema='conditioning-update-cpu-validation-v1', complete=True,
|
||||
epoch_authority_sha256=pins[str(ep)], parent_checkpoint_manifest_sha256=parent['manifest_sha256'],
|
||||
update_files_sha256={name: pins[str(files[name])] for name in UPDATE_FILES},
|
||||
before_overlay_sha256=pins[str(paths['before_overlay'])], before_manifest_sha256=pins[str(paths['before_manifest'])],
|
||||
after_overlay_sha256=pins[str(paths['after_overlay'])], after_manifest_sha256=pins[str(paths['after_manifest'])],
|
||||
before_delta_raw_sha256=R._raw(before['plastic_delta_mv']), after_delta_raw_sha256=R._raw(after['plastic_delta_mv']),
|
||||
update_receipt_payload_sha256=receipt['payload_sha256'],
|
||||
validator_source=dict(path=str(sources['cpu_validator_source']), sha256=pins[str(sources['cpu_validator_source'])]),
|
||||
frozen_U_source_sha256=SOURCE_PINS['conditioning_update_source'], frozen_U_verify_receipt_recomputed=True,
|
||||
actual_sealed_events_used=True, full_candidate_mapping_verified=True, brain_executed=False, learning_pass_claimed=False)
|
||||
R.require(_canonical(cpu) == _canonical(expected_cpu), 'External CPU recomputation receipt mismatch')
|
||||
return binding
|
||||
|
||||
|
||||
def validate_authority(authority_json, authority_sha256, *, _seen=None):
|
||||
"""Read-only CPU admission. Does not recompute U, run E, import Torch or restore.
|
||||
|
||||
Returns value/authority/authority_sha256, paths, pins (absolute str -> SHA),
|
||||
sources, parent, case_dir/spec, helper, before_plan/after_plan/before_meta/
|
||||
after_meta; suitable for an independent monolithic oracle without restore.
|
||||
"""
|
||||
pins = {}
|
||||
authority_path = _entry(dict(path=str(authority_json), sha256=authority_sha256), pins)
|
||||
_check(pins)
|
||||
value = R._read_json(authority_path)
|
||||
fields = {'schema', 'boundary_id', 'registration_sha256', 'transition', 'diagnostic_mode', 'input_policy',
|
||||
'case', 'parent', 'global_tick_offset', 'overlay_before', 'overlay_after',
|
||||
'expected_effective_weight_before_sha256', 'expected_effective_weight_after_sha256', 'update',
|
||||
'cpu_validation', 'source_files', 'frozen_inputs'}
|
||||
R.require(type(value) is dict and set(value) == fields and value['schema'] == SCHEMA, 'Boundary authority schema mismatch')
|
||||
R.require(type(value['boundary_id']) is str and value['boundary_id'].strip() == value['boundary_id'] and value['boundary_id'], 'Invalid boundary ID')
|
||||
R.require(R._sha(value['registration_sha256']) and value['transition'] in ('epoch_update', 'idle') and
|
||||
value['diagnostic_mode'] in ('reference', 'light'), 'Invalid boundary scope')
|
||||
R.require(type(value['case']) is dict and set(value['case']) == {'spec', 'requests'}, 'Exact case pins required')
|
||||
paths = {key: _entry(value['case'][role], pins) for key, role in (('case_spec', 'spec'), ('requests', 'requests'))}
|
||||
for moment in ('before', 'after'):
|
||||
pair = value['overlay_' + moment]
|
||||
R.require(type(pair) is dict and set(pair) == {'file', 'manifest'}, 'Exact overlay pair required')
|
||||
paths[moment + '_overlay'] = _entry(pair['file'], pins)
|
||||
paths[moment + '_manifest'] = _entry(pair['manifest'], pins)
|
||||
source_values = value['source_files']
|
||||
R.require(type(source_values) is dict and set(source_values) == set(SOURCE_PINS) |
|
||||
{'updated_continuation_source', 'cpu_validator_source'}, 'Exact source roles required')
|
||||
sources = {name: _entry(entry, pins) for name, entry in source_values.items()}
|
||||
for name, sha in SOURCE_PINS.items():
|
||||
R.require(pins[str(sources[name])] == sha, 'Frozen source may not be replaced: ' + name)
|
||||
R.require(sources['updated_continuation_source'] == Path(__file__).resolve() and
|
||||
sources['runtime_continuation_source'] == Path(C.__file__).resolve() and
|
||||
sources['runtime_light_source'] == Path(R.__file__).resolve() and
|
||||
sources['cpu_validator_source'] == Path(__file__).resolve().parent / 'validate_update_cpu.py',
|
||||
'Loaded runtime/CPU validator source path differs')
|
||||
R.require(type(value['frozen_inputs']) is dict and value['frozen_inputs'], 'Full frozen inputs required')
|
||||
for path, sha in value['frozen_inputs'].items():
|
||||
_entry(dict(path=path, sha256=sha), pins)
|
||||
p = value['parent']
|
||||
R.require(type(p) is dict and set(p) == {'directory', 'checkpoint_manifest_sha256'} and Path(p['directory']).is_absolute(), 'Exact parent authority required')
|
||||
parentdir = Path(p['directory']).resolve(strict=True)
|
||||
_entry(dict(path=str(parentdir / MANIFEST), sha256=p['checkpoint_manifest_sha256']), pins)
|
||||
_check(pins)
|
||||
parent = load_checkpoint(parentdir, p['checkpoint_manifest_sha256'], _seen=_seen)
|
||||
R.require(type(value['global_tick_offset']) is int and value['global_tick_offset'] == parent['global_next_tick'], 'Wrong absolute continuation clock')
|
||||
case = paths['case_spec'].parent
|
||||
R.require(paths['case_spec'].name == 'spec.json' and paths['requests'] == case / 'requests.npz', 'Case filenames differ')
|
||||
spec = R._read_json(paths['case_spec'])
|
||||
R.require(spec.get('parent_checkpoint_manifest_sha256') == p['checkpoint_manifest_sha256'] and
|
||||
type(spec.get('global_tick_offset')) is int and spec['global_tick_offset'] == value['global_tick_offset'], 'Case parent/clock differs')
|
||||
fresh = dict(spec)
|
||||
fresh.pop('parent_checkpoint_manifest_sha256')
|
||||
R.validate_spec(fresh, case)
|
||||
R.require(parent['global_next_tick'] + spec['steps'] <= np.iinfo(np.int64).max, 'Global clock overflow')
|
||||
_requests(paths['requests'], spec, value['input_policy'])
|
||||
previous = C._parent_spec(parent)
|
||||
for key in ('dt_ms', 'model', 'apl', 'apl_delay_steps'):
|
||||
R.require(_canonical(spec[key]) == _canonical(previous[key]), 'Frozen dynamics differ: ' + key)
|
||||
for key in ('graph_dir', 'apl_bundle_dir'):
|
||||
R.require(Path(spec[key]).resolve(strict=True) == Path(previous[key]).resolve(strict=True), 'Frozen directory differs')
|
||||
R.require(_digest(spec['coefficients_path']) == parent['summary']['input_sha256']['coefficients.json'] and
|
||||
_digest(Path(spec['graph_dir']) / 'weights.npy') == parent['summary']['input_sha256']['base_weights.npy'], 'Base/coefficients differ')
|
||||
required = [Path(spec['graph_dir']).resolve() / n for n in GRAPH_FILES] + [Path(spec['apl_bundle_dir']).resolve() / n for n in APL_FILES]
|
||||
required.append(Path(spec['coefficients_path']).resolve(strict=True))
|
||||
R.require(all(str(path) in value['frozen_inputs'] for path in required), 'Full graph/APL/coeff pins missing')
|
||||
helper, before, bm, bpins = R.load_overlay(paths['before_overlay'], paths['before_manifest'])
|
||||
helper2, after, am, apins = R.load_overlay(paths['after_overlay'], paths['after_manifest'])
|
||||
R.require(helper2 is helper, 'Overlay cache owner differs')
|
||||
for path, sha in {**bpins, **apins}.items():
|
||||
_entry(dict(path=str(path), sha256=sha), pins)
|
||||
for relative, sha in R.PINS.items():
|
||||
path = (Path(am['aj_model_dir']).resolve().parent / relative).resolve(strict=True)
|
||||
R.require(value['frozen_inputs'].get(str(path)) == sha, 'Compiled/source dependency authority missing: ' + relative)
|
||||
for key in ('mask_path', 'mask_sha256', 'base_candidate_path', 'base_candidate_sha256', 'aj_model_dir', 'am_overlay_path', 'am_overlay_sha256'):
|
||||
R.require(bm[key] == am[key], 'Before/after anatomical/source authority differs: ' + key)
|
||||
R.require(_digest(parentdir / 'overlay-input.npz') == pins[str(paths['before_overlay'])] and
|
||||
_digest(parentdir / 'overlay-manifest.json') == pins[str(paths['before_manifest'])], 'Before snapshot differs from actual neural parent')
|
||||
R.require(parent['overlay']['delta_raw_sha256'] == R._raw(before['plastic_delta_mv']), 'Parent delta raw identity mismatch')
|
||||
for key in ('expected_effective_weight_before_sha256', 'expected_effective_weight_after_sha256'):
|
||||
R.require(R._sha(value[key]), 'Expected effective SHA required')
|
||||
before_effective = _expected_effective(helper, before, spec)
|
||||
after_effective = _expected_effective(helper, after, spec)
|
||||
R.require(before_effective == value['expected_effective_weight_before_sha256'] == parent['summary']['effective_weights_raw_sha256'], 'Before effective weights differ')
|
||||
R.require(after_effective == value['expected_effective_weight_after_sha256'], 'After effective weights differ')
|
||||
paths.update(epoch_authority=None, cpu_validation=None)
|
||||
binding = None
|
||||
if value['transition'] == 'epoch_update':
|
||||
R.require(parent['fresh'] is True, 'An update boundary is allowed only once, from fresh AN parent')
|
||||
binding = _epoch_update(value, paths, sources, pins, parent, before, after, bm, am)
|
||||
root = authority_sha256
|
||||
else:
|
||||
R.require(parent['manifest']['schema'] == CHECKPOINT_SCHEMA and value['update'] is None and value['cpu_validation'] is None,
|
||||
'Idle requires own updated parent and no new update authority')
|
||||
R.require(pins[str(paths['before_overlay'])] == pins[str(paths['after_overlay'])] and
|
||||
pins[str(paths['before_manifest'])] == pins[str(paths['after_manifest'])] and
|
||||
before_effective == after_effective, 'Idle changed the installed snapshot')
|
||||
R.require(parent['input_policy'] == 'empty_idle', 'A probe branch cannot feed back into a continuation lineage')
|
||||
root = parent['update_root_authority_sha256']
|
||||
_check(pins)
|
||||
return dict(value=value, authority=authority_path, authority_sha256=authority_sha256, paths=paths, pins=pins,
|
||||
sources=sources, parent=parent, case_dir=case, spec=spec, helper=helper, before_plan=before, after_plan=after,
|
||||
before_meta=bm, after_meta=am, delta_binding=binding, update_root_authority_sha256=root)
|
||||
|
||||
|
||||
class UpdatedRuntime(C.ContinuedRuntime):
|
||||
"""Only weight admission differs from C; restoration and kernels unchanged."""
|
||||
def __init__(self, *args, authority, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.authority = authority
|
||||
self.restore_audit = None
|
||||
|
||||
def install(self, *args, **kwargs):
|
||||
R.require(self.installations == 0 and self.restorations == 0, 'Double/belated weight installation')
|
||||
R._Runtime.install(self, *args, **kwargs) # Original base + full delta once; not old effective + delta.
|
||||
R.require(self.effective_sha == self.authority['value']['expected_effective_weight_after_sha256'], 'Installed weight differs from authorized after')
|
||||
|
||||
def restore(self, v, g, ref, counts, ring, apl_ring, apl, upload):
|
||||
super().restore(v, g, ref, counts, ring, apl_ring, apl, upload)
|
||||
expected = dict(v=self.parent['state']['v'], g=self.parent['state']['g'], ref=self.parent['state']['ref'],
|
||||
spike_ring=C.rotate_spike_ring(self.parent['terminal']['spike_ring'], int(self.parent['terminal']['next_tick'])),
|
||||
apl_pending=self.parent['terminal']['apl_pending'], apl_state=self.parent['terminal']['apl_state'])
|
||||
actual = dict(v=v, g=g, ref=ref, spike_ring=ring, apl_pending=apl_ring, apl_state=apl.state)
|
||||
for key, tensor in actual.items():
|
||||
R.require(_same(tensor.detach().cpu().numpy(), expected[key]), 'Restoration changed actual state bytes: ' + key)
|
||||
self.restore_audit = dict(restored_raw_sha256={key: R._raw(a) for key, a in expected.items()},
|
||||
all_state_and_queue_bytes_exact=True, existing_g_rescaled=False, retroactive_arrival_reweighting=False,
|
||||
pending_spike_arrivals_use_current_installed_weight=True, pending_APL_samples_preserved=True,
|
||||
boundary_installations=1, restorations=1, learning_pass_claimed=False)
|
||||
|
||||
def summary(self, value):
|
||||
result = super().summary(value)
|
||||
result.update(updated_boundary_schema=SCHEMA, boundary_authority_sha256=self.authority['authority_sha256'],
|
||||
update_root_authority_sha256=self.authority['update_root_authority_sha256'],
|
||||
boundary_transition=self.authority['value']['transition'], input_policy=self.authority['value']['input_policy'],
|
||||
weight_update_at_boundary_authorized=True, frozen_same_weight_retention_claimed=False)
|
||||
return result
|
||||
|
||||
|
||||
def compile_updated(aj, runtime, mode):
|
||||
tree, audit = C.derive_continued(Path(aj.__file__).read_bytes(), mode)
|
||||
namespace = dict(aj.__dict__)
|
||||
namespace.update(__name__=__name__ + '.derived_' + mode, __file__=str(Path(__file__).resolve()),
|
||||
_runtime=runtime, _continuation=runtime, write_json=runtime.write_json, audit_sequence=runtime.audit_sequence)
|
||||
exec(compile(tree, str(Path(__file__).resolve()) + '::updated-continuation-' + mode, 'exec'), namespace)
|
||||
return namespace['run_gpu'], audit
|
||||
|
||||
|
||||
def _record(directory, seen):
|
||||
provenance = R._read_json(directory / 'runtime-provenance.json')
|
||||
R.require(provenance.get('schema') == PROVENANCE_SCHEMA and provenance.get('complete') is True and
|
||||
provenance.get('source_sha256') == _digest(__file__) and
|
||||
Path(provenance['source_file']).resolve() == Path(__file__).resolve(), 'Not a genuine new continuation record')
|
||||
R.require(provenance.get('old_globals_patched') is False and provenance.get('weights_updated_during_run') is False and
|
||||
provenance.get('U_recomputed_here') is False and provenance.get('learning_pass_claimed') is False, 'Invalid continuation scope')
|
||||
C._verify_receipt_hashes(directory, provenance)
|
||||
R.require(provenance.get('state_sha256') == _digest(directory / 'state.npz'), 'Actual state is not bound')
|
||||
authority = validate_authority(provenance['authority_file'], provenance['authority_sha256'], _seen=seen)
|
||||
parent, spec, value = authority['parent'], authority['spec'], authority['value']
|
||||
steps, offset = spec['steps'], parent['global_next_tick']
|
||||
R.require(provenance['input_sha256'] == authority['pins'], 'Receipt input closure differs from authority')
|
||||
R.require(provenance.get('mode') == value['diagnostic_mode'] and
|
||||
provenance.get('parent_checkpoint_manifest_sha256') == parent['manifest_sha256'] and
|
||||
provenance.get('global_tick_offset') == offset and provenance.get('global_next_tick') == offset+steps and
|
||||
provenance.get('external_CPU_validation_receipt_bound') is (value['transition'] == 'epoch_update') and
|
||||
provenance.get('external_registration_process_and_probe_semantics_verified_here') is False,
|
||||
'Runtime provenance boundary/clock/scope differs')
|
||||
_, expected_ast = C.derive_continued((Path(authority['after_meta']['aj_model_dir']) / 'gpu_timing.py').read_bytes(), value['diagnostic_mode'])
|
||||
R.require(provenance.get('ast') == expected_ast, 'Derived source AST provenance differs')
|
||||
summary = R._read_json(directory / 'summary.json')
|
||||
finite = R._read_json(directory / 'finite-audit.json')
|
||||
for name, expected in dict(complete=True, pass_all=True, all_finite=True, steps=steps, completed_ticks=steps,
|
||||
nodes=C.N, edges=C.E, precision='float64', apl_precision='float32', within_trial_weight_updates=False,
|
||||
checkpoint_continuation_used=True, global_tick_offset=offset, global_next_tick=offset+steps,
|
||||
explicit_steps_executed=steps, max_steps=spec['max_steps'], hidden_early_stop=False,
|
||||
entire_neural_trial_executed=True, record_history=False, counts_scope='segment_only_not_lifetime',
|
||||
event_tick_scope='segment_local', weight_update_at_boundary_authorized=True, frozen_same_weight_retention_claimed=False,
|
||||
parent_checkpoint_manifest_sha256=parent['manifest_sha256'], diagnostic_mode=value['diagnostic_mode'],
|
||||
boundary_authority_sha256=authority['authority_sha256'], update_root_authority_sha256=authority['update_root_authority_sha256'],
|
||||
updated_boundary_schema=SCHEMA, boundary_transition=value['transition'], input_policy=value['input_policy'],
|
||||
effective_weights_raw_sha256=value['expected_effective_weight_after_sha256']).items():
|
||||
R.require(_canonical(summary.get(name)) == _canonical(expected), 'Summary binding mismatch: ' + name)
|
||||
R.require(finite.get('all_finite') is True and finite.get('first_failure_tick') == -1 and
|
||||
finite.get('finite_observed_ticks') == steps, 'Missing full finite coverage')
|
||||
expected_input = {'spec.json': authority['pins'][str(authority['paths']['case_spec'])],
|
||||
'requests.npz': authority['pins'][str(authority['paths']['requests'])],
|
||||
'base_weights.npy': _digest(Path(spec['graph_dir']) / 'weights.npy'), 'coefficients.json': _digest(spec['coefficients_path'])}
|
||||
R.require(summary.get('input_sha256') == expected_input, 'Summary case/base inputs differ')
|
||||
state = C._npz(directory / 'state.npz', ('step', 'neuron_idx', 'counts', 'v', 'g', 'ref'))
|
||||
terminal = C._npz(directory / 'terminal-queues.npz', ('spike_ring', 'apl_state', 'apl_pending', 'next_tick'))
|
||||
C.validate_state(state, terminal, steps, fresh=False)
|
||||
if steps < 19:
|
||||
restored = C.rotate_spike_ring(parent['terminal']['spike_ring'], int(parent['terminal']['next_tick']))
|
||||
R.require(_same(terminal['spike_ring'][steps:], restored[steps:]), 'Unwritten carried spike slots differ')
|
||||
if steps < 18:
|
||||
R.require(_same(terminal['apl_pending'][:18-steps], parent['terminal']['apl_pending'][steps:]), 'Carried APL tail differs')
|
||||
pending = np.load(directory / 'apl-pending-tail.float32.npy', allow_pickle=False)
|
||||
timing = R._read_json(directory / 'apl-timing-audit.json')
|
||||
R.require(_same(pending, terminal['apl_pending']) and timing.get('pending_raw_sha256') == R._raw(pending) and
|
||||
timing.get('apl_delay_steps') == 18 and timing.get('brain_tail_advanced') is False and
|
||||
timing.get('final_apl_state_u32_bits') == terminal['apl_state'].view(np.uint32).tolist() and
|
||||
timing.get('global_tick_offset') == offset and timing.get('global_next_tick') == offset+steps and
|
||||
timing.get('initial_queue_raw_sha256') == R._raw(parent['terminal']['apl_pending']), 'APL metadata/terminal mismatch')
|
||||
overlay = R._read_json(directory / 'overlay-audit.json')
|
||||
R.require(overlay.get('complete') is True and overlay.get('weights_updated_during_run') is False and
|
||||
overlay.get('effective_weights_raw_sha256') == value['expected_effective_weight_after_sha256'] and
|
||||
overlay.get('delta_raw_sha256') == R._raw(authority['after_plan']['plastic_delta_mv']) and
|
||||
overlay.get('mask_sha256') == R.MASK_SHA and overlay.get('am_helper_sha256') == R.AM_OVERLAY_SHA, 'Installed snapshot receipt mismatch')
|
||||
for dest, source in (('overlay-input.npz', 'after_overlay'), ('overlay-manifest.json', 'after_manifest')):
|
||||
R.require(_digest(directory / dest) == authority['pins'][str(authority['paths'][source])], 'Copied after snapshot differs')
|
||||
receipt = R._read_json(directory / RECEIPT)
|
||||
payload = C._tree_hashes(directory)
|
||||
payload.pop(RECEIPT, None)
|
||||
expected_receipt = dict(schema='conditioning-updated-receipt-v1', complete=True,
|
||||
authority_file=str(authority['authority']), authority_sha256=authority['authority_sha256'],
|
||||
parent_checkpoint_dir=str(parent['directory']), parent_checkpoint_manifest_sha256=parent['manifest_sha256'],
|
||||
global_tick_offset=offset, global_next_tick=offset+steps, segment_steps=steps,
|
||||
update_root_authority_sha256=authority['update_root_authority_sha256'], input_policy=value['input_policy'],
|
||||
payload_sha256=payload, weights_updated_during_run=False, counts_scope='segment_only_not_lifetime',
|
||||
checkpoint_continuation_verified_by_GPU_comparison=False, learning_pass_claimed=False)
|
||||
R.require(_canonical(receipt) == _canonical(expected_receipt), 'New receipt payload/ancestry mismatch')
|
||||
restored = dict(v=parent['state']['v'], g=parent['state']['g'], ref=parent['state']['ref'],
|
||||
spike_ring=C.rotate_spike_ring(parent['terminal']['spike_ring'], int(parent['terminal']['next_tick'])),
|
||||
apl_pending=parent['terminal']['apl_pending'], apl_state=parent['terminal']['apl_state'])
|
||||
boundary = R._read_json(directory / 'boundary-restore-audit.json')
|
||||
R.require(boundary == dict(restored_raw_sha256={k:R._raw(a) for k,a in restored.items()},
|
||||
all_state_and_queue_bytes_exact=True, existing_g_rescaled=False, retroactive_arrival_reweighting=False,
|
||||
pending_spike_arrivals_use_current_installed_weight=True, pending_APL_samples_preserved=True,
|
||||
boundary_installations=1, restorations=1, learning_pass_claimed=False), 'Boundary restore audit differs from real parent')
|
||||
return dict(directory=directory, summary=summary, provenance=provenance, overlay=overlay, state=state, terminal=terminal,
|
||||
steps=steps, global_tick_offset=offset, global_next_tick=offset+steps, fresh=False,
|
||||
ancestry_directories=[directory, *parent['ancestry_directories']], input_policy=value['input_policy'],
|
||||
update_root_authority_sha256=authority['update_root_authority_sha256'])
|
||||
|
||||
|
||||
def load_checkpoint(checkpoint_dir, expected_sha, *, _seen=None):
|
||||
directory = Path(checkpoint_dir).resolve(strict=True)
|
||||
R.require(R._sha(expected_sha) and _digest(directory / MANIFEST) == expected_sha, 'External checkpoint pin differs')
|
||||
manifest = R._read_json(directory / MANIFEST)
|
||||
if manifest.get('schema') == 'phase4an-checkpoint-v1':
|
||||
return C.load_checkpoint(directory, expected_sha, _seen=_seen)
|
||||
seen = set() if _seen is None else set(_seen)
|
||||
R.require(directory not in seen, 'Updated checkpoint ancestry cycle')
|
||||
seen.add(directory)
|
||||
R.require(set(manifest) == {'schema', 'complete', 'files_sha256', 'segment_steps', 'global_tick_offset', 'global_next_tick',
|
||||
'counts_scope', 'update_root_authority_sha256', 'input_policy', 'learning_pass_claimed',
|
||||
'checkpoint_continuation_verified_by_GPU_comparison'} and
|
||||
manifest.get('schema') == CHECKPOINT_SCHEMA and manifest.get('complete') is True and
|
||||
manifest.get('learning_pass_claimed') is False and manifest.get('checkpoint_continuation_verified_by_GPU_comparison') is False and
|
||||
manifest.get('counts_scope') == 'segment_only' and manifest.get('files_sha256') == C._tree_hashes(directory), 'New checkpoint exact inventory differs')
|
||||
record = _record(directory, seen)
|
||||
for key in ('global_tick_offset', 'global_next_tick', 'update_root_authority_sha256', 'input_policy'):
|
||||
R.require(manifest.get(key) == record[key], 'Checkpoint metadata mismatch: ' + key)
|
||||
R.require(manifest.get('segment_steps') == record['steps'] and manifest['files_sha256'] == C._tree_hashes(directory) and
|
||||
_digest(directory / MANIFEST) == expected_sha, 'Checkpoint changed while loading')
|
||||
record.update(manifest=manifest, manifest_sha256=expected_sha)
|
||||
return record
|
||||
|
||||
|
||||
def seal_checkpoint(checkpoint_dir):
|
||||
directory = Path(checkpoint_dir).resolve(strict=True)
|
||||
R.require(not (directory / MANIFEST).exists(), 'Checkpoint is already sealed')
|
||||
before = C._tree_hashes(directory)
|
||||
record = _record(directory, {directory})
|
||||
R.require(before == C._tree_hashes(directory), 'Checkpoint changed while sealing')
|
||||
value = dict(schema=CHECKPOINT_SCHEMA, complete=True, files_sha256=before, segment_steps=record['steps'],
|
||||
global_tick_offset=record['global_tick_offset'], global_next_tick=record['global_next_tick'],
|
||||
counts_scope='segment_only', update_root_authority_sha256=record['update_root_authority_sha256'],
|
||||
input_policy=record['input_policy'], learning_pass_claimed=False,
|
||||
checkpoint_continuation_verified_by_GPU_comparison=False)
|
||||
R._save(directory / MANIFEST, value)
|
||||
return dict(path=str(directory / MANIFEST), sha256=_digest(directory / MANIFEST), **value)
|
||||
|
||||
|
||||
def run(authority_json, authority_sha256, out_dir, build_root, *, mode='light'):
|
||||
R.require(sys.dont_write_bytecode, 'Use python -B')
|
||||
admitted = validate_authority(authority_json, authority_sha256)
|
||||
value, parent, spec = admitted['value'], admitted['parent'], admitted['spec']
|
||||
R.require(mode == value['diagnostic_mode'], 'Mode differs from authority')
|
||||
protected = [*parent['ancestry_directories'], *(Path(path).parent for path in admitted['pins'])]
|
||||
case, out, build = R.execution_paths(admitted['case_dir'], out_dir, build_root, protected)
|
||||
ajdir = Path(admitted['after_meta']['aj_model_dir'])
|
||||
R._load('timing_queue', ajdir / 'timing_queue.py', R.PINS['apl-timing-lab-v1/timing_queue.py'])
|
||||
aj = R._load('conditioning_updated_sealed_AJ', ajdir / 'gpu_timing.py', R.AJ_SHA)
|
||||
runtime = UpdatedRuntime(mode, spec, admitted['helper'], admitted['after_plan'], admitted['after_meta'],
|
||||
admitted['pins'], aj.torch, admitted['paths']['after_overlay'], admitted['paths']['after_manifest'],
|
||||
parent=parent, authority=admitted)
|
||||
function, ast_audit = compile_updated(aj, runtime, mode)
|
||||
try:
|
||||
inherited = function(case, out, build)
|
||||
R.require(runtime.finished and runtime.restorations == runtime.installations == 1 and inherited['complete'], 'Incomplete new continuation')
|
||||
R.require(inherited['effective_weights_raw_sha256'] == value['expected_effective_weight_after_sha256'], 'Runtime effective identity differs')
|
||||
_check(admitted['pins'])
|
||||
load_checkpoint(parent['directory'], parent['manifest_sha256'])
|
||||
summary = R._read_json(out / 'summary.json')
|
||||
R.require(summary == runtime.summary(inherited), 'Stored updated summary differs')
|
||||
R._save(out / 'boundary-restore-audit.json', runtime.restore_audit)
|
||||
provenance = dict(schema=PROVENANCE_SCHEMA, complete=True, mode=mode,
|
||||
source_file=str(Path(__file__).resolve()), source_sha256=_digest(__file__),
|
||||
authority_file=str(admitted['authority']), authority_sha256=authority_sha256,
|
||||
ast=ast_audit, input_sha256=admitted['pins'], old_globals_patched=False, weights_updated_during_run=False,
|
||||
global_tick_offset=parent['global_next_tick'], global_next_tick=parent['global_next_tick']+spec['steps'],
|
||||
parent_checkpoint_manifest_sha256=parent['manifest_sha256'], U_recomputed_here=False,
|
||||
external_CPU_validation_receipt_bound=value['transition'] == 'epoch_update',
|
||||
external_registration_process_and_probe_semantics_verified_here=False, learning_pass_claimed=False)
|
||||
for key, name in (('summary_sha256','summary.json'), ('finite_audit_sha256','finite-audit.json'),
|
||||
('terminal_queues_sha256','terminal-queues.npz'), ('overlay_audit_sha256','overlay-audit.json'), ('state_sha256','state.npz')):
|
||||
provenance[key] = _digest(out / name)
|
||||
R._save(out / 'runtime-provenance.json', provenance)
|
||||
receipt = dict(schema='conditioning-updated-receipt-v1', complete=True,
|
||||
authority_file=str(admitted['authority']), authority_sha256=authority_sha256,
|
||||
parent_checkpoint_dir=str(parent['directory']), parent_checkpoint_manifest_sha256=parent['manifest_sha256'],
|
||||
global_tick_offset=parent['global_next_tick'], global_next_tick=parent['global_next_tick']+spec['steps'],
|
||||
segment_steps=spec['steps'], update_root_authority_sha256=admitted['update_root_authority_sha256'],
|
||||
input_policy=value['input_policy'], payload_sha256=C._tree_hashes(out), weights_updated_during_run=False,
|
||||
counts_scope='segment_only_not_lifetime', checkpoint_continuation_verified_by_GPU_comparison=False, learning_pass_claimed=False)
|
||||
R._save(out / RECEIPT, receipt)
|
||||
sealed = seal_checkpoint(out)
|
||||
return dict(summary, checkpoint_manifest_sha256=sealed['sha256'])
|
||||
except Exception as error:
|
||||
if out.is_dir() and not (out / 'updated-error.json').exists():
|
||||
R._save(out / 'updated-error.json', dict(complete=False, type=type(error).__name__, message=str(error), retry_forbidden=True))
|
||||
raise
|
||||
@@ -0,0 +1,174 @@
|
||||
"""Fresh CPU-process revalidation of a sealed epoch's actual update.
|
||||
|
||||
This does not run a brain or E.postprocess_epoch and writes only one exclusive
|
||||
receipt. The caller must pin the source, authority and successful process to its
|
||||
registration. A supplied SHA is not independent scientific authorization.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import importlib.util
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
import numpy as np
|
||||
|
||||
LAB = Path(__file__).resolve().parent.parent/'olfactory-conditioning-lab-v1'
|
||||
E_SHA = '757935a4815d9f625640df685184ed3fe44a8845323562796da7aa43cbb194e1'
|
||||
Q_SHA = 'b88fd9a88d9f92d5c4d042b90f2129b015e8d4bd810c41351ee573241e2d4c2e'
|
||||
U_SHA = '96efff678cff910654eb08e86f1a17789e4e5589e340345f419c7027a7d547e2'
|
||||
CMP_SHA = '5a2403f11bc08d65a9d242ac2cf9686b850e0c3680d65659f785e9b6b50c0238'
|
||||
FILES = ('chain-receipt.json','update-receipt.json','delta-after.npz','overlay-manifest.json')
|
||||
|
||||
|
||||
def require(ok,message):
|
||||
if not ok: raise ValueError(message)
|
||||
|
||||
|
||||
def digest(path):
|
||||
h=hashlib.sha256()
|
||||
with Path(path).open('rb') as stream:
|
||||
for b in iter(lambda:stream.read(8<<20),b''):h.update(b)
|
||||
return h.hexdigest()
|
||||
|
||||
|
||||
def same(a,b): return a.dtype==b.dtype and a.shape==b.shape and a.tobytes()==b.tobytes()
|
||||
|
||||
|
||||
def unlinked(path):
|
||||
path=Path(path).absolute()
|
||||
require(not any(p.is_symlink() or (hasattr(p,'is_junction') and p.is_junction())
|
||||
for p in (path,*path.parents)), 'Linked receipt/update path forbidden')
|
||||
return path
|
||||
|
||||
|
||||
def load(name,path,expected):
|
||||
raw=Path(path).read_bytes()
|
||||
require(hashlib.sha256(raw).hexdigest()==expected and name not in sys.modules,'Unverified source/module binding')
|
||||
spec=importlib.util.spec_from_file_location(name,path);module=importlib.util.module_from_spec(spec)
|
||||
sys.modules[name]=module
|
||||
exec(compile(raw,str(path),'exec'),module.__dict__)
|
||||
return module
|
||||
|
||||
|
||||
def chain_binding(chain,authority,authority_sha,pins,paths,checkpoint,hashes):
|
||||
require(chain.get('schema')=='phase4an-epoch-postprocess-chain-v1' and chain.get('complete') is True,
|
||||
'Incomplete epoch update chain')
|
||||
for flag in ('weights_installed','brain_executed','learning_pass_claimed','candidate_generated'):
|
||||
require(chain.get(flag) is False,'Wrong chain scope: '+flag)
|
||||
require(chain['coordinator_source_sha256']==E_SHA and chain['authority_sha256']==authority_sha and
|
||||
chain['epoch_id']==authority['epoch_id'] and chain['command']==authority['command'] and
|
||||
chain['diagnostic_mode']==authority['diagnostic_mode'],'Epoch authority/command differs')
|
||||
require(chain['source_neural_checkpoint_dir']==str(checkpoint) and
|
||||
chain['source_neural_checkpoint_manifest_sha256']==authority['checkpoint_manifest_sha256'] and
|
||||
chain['input_files_sha256']=={str(p):v for p,v in pins.items()},'Actual checkpoint/input binding differs')
|
||||
for field,role in (('source_state_file_sha256','state'),('source_spec_sha256','spec'),
|
||||
('source_requests_sha256','requests'),('before_overlay_file_sha256','overlay_before'),
|
||||
('before_overlay_manifest_sha256','overlay_manifest_before')):
|
||||
require(chain[field]==pins[paths[role]],'Chain input differs: '+role)
|
||||
expected={name:hashes[name] for name in FILES if name!='chain-receipt.json'}
|
||||
require(chain['output_files_sha256']==expected and chain['after_overlay_file_sha256']==hashes['delta-after.npz'] and
|
||||
chain['after_overlay_manifest_sha256']==hashes['overlay-manifest.json'],'Chain output differs')
|
||||
|
||||
|
||||
def validate(epoch_authority,authority_sha,update_dir,chain_sha,receipt_file):
|
||||
require(sys.dont_write_bytecode and 'torch' not in sys.modules and 'runtime_light' not in sys.modules,
|
||||
'Run in a fresh Python -B CPU process')
|
||||
os.environ['CUDA_VISIBLE_DEVICES']=''
|
||||
e=load('_conditioning_execution_E_validator',LAB/'conditioning_epoch.py',E_SHA)
|
||||
load('engineering_compare',LAB/'engineering_compare.py',CMP_SHA)
|
||||
q=load('_conditioning_execution_Q_validator',LAB/'conditioning_preflight_compare.py',Q_SHA)
|
||||
value,paths,pins,checkpoint,authority_path=e._authority(epoch_authority,authority_sha)
|
||||
c,r,u=e._production_dependencies(paths,pins) # The only R is C.R; no ordinary runtime loader.
|
||||
directory=unlinked(update_dir).resolve(strict=True);out=unlinked(receipt_file)
|
||||
protected={checkpoint,directory,*[p.parent for p in pins]}
|
||||
require(out.parent.is_dir() and not out.exists() and not any(out.resolve().is_relative_to(p) for p in protected),
|
||||
'Receipt must be new and outside every frozen input/output directory')
|
||||
require(set(p.name for p in directory.iterdir())==set(FILES) and
|
||||
all((directory/n).is_file() and not (directory/n).is_symlink() for n in FILES),'Expected exact four update files')
|
||||
hashes={n:digest(directory/n) for n in FILES}
|
||||
require(e._sha(chain_sha) and hashes['chain-receipt.json']==chain_sha,'Chain differs from external SHA')
|
||||
own=digest(__file__);chain=e._read(directory/'chain-receipt.json')
|
||||
chain_binding(chain,value,authority_sha,pins,paths,checkpoint,hashes)
|
||||
parent=c.load_checkpoint(checkpoint,value['checkpoint_manifest_sha256'])
|
||||
command=value['command'];spec=e._read(paths['spec'])
|
||||
r.validate_spec(spec,paths['spec'].parent)
|
||||
require(parent['fresh'] is True and parent['global_tick_offset']==0 and parent['steps']==command['steps']==spec['steps'] and
|
||||
parent['summary']['diagnostic_mode']==value['diagnostic_mode'],'Wrong actual epoch/state scope')
|
||||
for role in ('spec','requests','overlay_before','overlay_manifest_before'):
|
||||
require(parent['provenance']['input_sha256'].get(str(paths[role]))==pins[paths[role]],'Runtime input differs: '+role)
|
||||
require(parent['manifest']['files_sha256']['state.npz']==pins[paths['state']],'State not sealed by this checkpoint')
|
||||
_,before,before_meta,_=r.load_overlay(paths['overlay_before'],paths['overlay_manifest_before'])
|
||||
_,after,after_meta,_=r.load_overlay(directory/'delta-after.npz',directory/'overlay-manifest.json')
|
||||
graph=Path(spec['graph_dir']).resolve();apl=Path(spec['apl_bundle_dir']).resolve()
|
||||
for location in [graph/n for n in e.GRAPH_FILES]+[apl/n for n in e.APL_FILES]+[Path(spec['coefficients_path']).resolve()]:
|
||||
require(location in pins,'Missing complete graph/APL/coefficient pin')
|
||||
require(paths['canonical_kc']==apl/'kc_globals.npy','Canonical KC path differs')
|
||||
for role,prefix in (('mask','mask'),('base_candidate','base_candidate'),('am_overlay_source','am_overlay')):
|
||||
require(Path(before_meta[prefix+'_path']).resolve()==paths[role] and before_meta[prefix+'_sha256']==pins[paths[role]],'Overlay input differs')
|
||||
aj=Path(before_meta['aj_model_dir']).resolve()
|
||||
for relative,sha in r.PINS.items():require(pins.get((aj.parent/relative).resolve())==sha,'Missing original dependency pin')
|
||||
mapping=e._npz(paths['candidate_map'],('edge_id','source_neuron_idx','target_neuron_idx','target_compartment_verbatim'))
|
||||
mask=np.load(paths['mask'],allow_pickle=False);kc=np.load(paths['kc'],allow_pickle=False)
|
||||
canonical=np.load(paths['canonical_kc'],allow_pickle=False);base=np.load(paths['base_candidate'],allow_pickle=False)
|
||||
e._vector(mask,'int64',14232,'mask');e._vector(kc,'int32',4064,'KC');e._vector(canonical,'int32',4064,'canonical KC')
|
||||
e._vector(base,'float32',14232,'base')
|
||||
require(np.all((mask>=0)&(mask<25582938)) and np.all(mask[1:]>mask[:-1]) and
|
||||
np.all((kc>=0)&(kc<166700)) and len(np.unique(kc))==len(kc),
|
||||
'Candidate/KC range or uniqueness differs')
|
||||
require(same(kc,canonical) and same(mask,mapping['edge_id']) and same(mask,before['edge_id']) and same(mask,after['edge_id']),
|
||||
'KC/candidate membership differs')
|
||||
require(same(base,before['base_candidate_mv']) and same(base,after['base_candidate_mv']),'Original base changed')
|
||||
maps={}
|
||||
try:
|
||||
for n,dtype,count in (('nodes','int32',166700),('edge_id','int64',25582938),('src','int32',25582938),('dst','int32',25582938)):
|
||||
maps[n]=np.load(graph/(n+'.npy'),allow_pickle=False,mmap_mode='r');e._vector(maps[n],dtype,count,n)
|
||||
require(np.array_equal(maps['nodes'],np.arange(166700,dtype=np.int32)) and same(maps['edge_id'][mask],mask),'Not canonical full graph')
|
||||
require(same(mapping['source_neuron_idx'],maps['src'][mask]) and same(mapping['target_neuron_idx'],maps['dst'][mask]),
|
||||
'Candidate endpoints differ from actual connectome')
|
||||
finally:
|
||||
for a in maps.values():a._mmap.close()
|
||||
state=e._npz(paths['state'],('step','neuron_idx','counts','v','g','ref'))
|
||||
require(all(same(state[n],parent['state'][n]) for n in state),'Actual sealed event/state mismatch')
|
||||
require(parent['overlay']['delta_raw_sha256']==r._raw(before['plastic_delta_mv']) and
|
||||
chain['runtime_delta_before_raw_sha256']==r._raw(before['plastic_delta_mv']) and
|
||||
chain['runtime_effective_weights_raw_sha256']==parent['summary']['effective_weights_raw_sha256'], 'Actual before installation differs')
|
||||
update=e._read(directory/'update-receipt.json')
|
||||
require(update['payload_sha256']==chain['update_receipt_payload_sha256'],'Update receipt chain differs')
|
||||
u.verify_receipt(update,step=state['step'],neuron_idx=state['neuron_idx'],kc=kc,candidate_edge_id=mask,
|
||||
candidate_sources=mapping['source_neuron_idx'],candidate_targets=mapping['target_neuron_idx'],
|
||||
candidate_compartments=mapping['target_compartment_verbatim'],delta_before=before['plastic_delta_mv'],base_candidate=base,
|
||||
steps=command['steps'],n_neurons=166700,compartment=command['compartment'],us_tick=command['us_tick'],
|
||||
d_command=command['d_command'],frozen=command['frozen'],trace_backend=command['trace_backend'],
|
||||
bridge_source=paths['eligibility_bridge_source'],phase4j_source=paths['phase4j_source'])
|
||||
binding=q.audit_delta_binding(before['plastic_delta_mv'],after['plastic_delta_mv'],after['plastic_delta_mv'],
|
||||
update_receipt=update,parent_snapshot_sha256=pins[paths['overlay_before']],child_manifest=after_meta)
|
||||
require(binding['pass_all'],'Actual after array differs from recomputed receipt')
|
||||
import torch
|
||||
require(os.environ['CUDA_VISIBLE_DEVICES']=='' and not torch.cuda.is_initialized(),'CPU verifier initialized CUDA')
|
||||
e._check_files(pins);c.load_checkpoint(checkpoint,value['checkpoint_manifest_sha256'])
|
||||
for file,sha in (('conditioning_epoch.py',E_SHA),('conditioning_preflight_compare.py',Q_SHA),('engineering_compare.py',CMP_SHA)):
|
||||
require(digest(LAB/file)==sha,'Verifier dependency changed')
|
||||
require(hashes=={n:digest(directory/n) for n in FILES} and own==digest(__file__),'Source/update changed during validation')
|
||||
receipt=dict(schema='conditioning-update-cpu-validation-v1',complete=True,epoch_authority_sha256=authority_sha,
|
||||
parent_checkpoint_manifest_sha256=value['checkpoint_manifest_sha256'],update_files_sha256=hashes,
|
||||
before_overlay_sha256=pins[paths['overlay_before']],before_manifest_sha256=pins[paths['overlay_manifest_before']],
|
||||
after_overlay_sha256=hashes['delta-after.npz'],after_manifest_sha256=hashes['overlay-manifest.json'],
|
||||
before_delta_raw_sha256=r._raw(before['plastic_delta_mv']),after_delta_raw_sha256=r._raw(after['plastic_delta_mv']),
|
||||
update_receipt_payload_sha256=update['payload_sha256'],validator_source=dict(path=str(Path(__file__).resolve()),sha256=own),
|
||||
frozen_U_source_sha256=U_SHA,frozen_U_verify_receipt_recomputed=True,actual_sealed_events_used=True,
|
||||
full_candidate_mapping_verified=True,brain_executed=False,learning_pass_claimed=False)
|
||||
e._save(out,receipt)
|
||||
return receipt
|
||||
|
||||
|
||||
if __name__=='__main__':
|
||||
parser=argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--authority',required=True);parser.add_argument('--authority-sha256',required=True)
|
||||
parser.add_argument('--update-dir',required=True);parser.add_argument('--chain-sha256',required=True)
|
||||
parser.add_argument('--receipt',required=True);args=parser.parse_args()
|
||||
validate(args.authority,args.authority_sha256,args.update_dir,args.chain_sha256,args.receipt)
|
||||
print(json.dumps(dict(complete=True,receipt=args.receipt,sha256=digest(args.receipt))),flush=True)
|
||||
@@ -0,0 +1,91 @@
|
||||
# Normal olfactory acquisition: independent D18 branch
|
||||
|
||||
This phase does not modify MaleCNS reference/runtime, Phase 1–4AQ data, the
|
||||
base graph, the 14,232 candidate edges, eligibility-v2, APL gain, cell thresholds,
|
||||
transmitter signs or any previously sealed failure. An engineering interface
|
||||
PASS is not evidence of learning.
|
||||
|
||||
## Fixed science
|
||||
|
||||
The original AO file (SHA-256
|
||||
`a7bda850ee87df4d9f647994e1a1a4074dfea5793184edb1822ab3d8c02e8216`)
|
||||
supplies master 20260930, all semantic seeds, ordered cues and control schedules.
|
||||
The old frozen evaluation policy supplies completed-epoch snapshot boundaries.
|
||||
There are 40 normal blocks: physiological/matched-energy × PAM15/PPL103 ×
|
||||
reciprocal reinforced odor × five training replicates. A is 4-ethylphenol, B is
|
||||
3-hexanone. Evaluation uses 80 independently registered input streams.
|
||||
|
||||
All seven arms are real: paired, D=0, frozen, random reward, unpaired, CS-only
|
||||
and DAN-only. 30,000 complete fresh training/control epochs and 3,920 real
|
||||
fresh A/B probes are required. Even identical baselines are executed, not
|
||||
relabelled copies. Snapshots 0/1/2/5/10/20/50 never authorize outcome selection.
|
||||
Only the 50-pairing terminal outcome determines acquisition. Every arm finishes
|
||||
its entire original schedule, including trailing neutral or blank epochs.
|
||||
|
||||
Epochs are 120 ms, CS is [0,100) ms, scheduled artificial US is at 90 ms.
|
||||
PAM15 and PPL103 use only their existing confirmed compartment-specific DAN
|
||||
identities. The positive/negative behavioral predictions are explicit model
|
||||
hypotheses, not a claim that every PAM/PPL neuron has that function. Scheduled
|
||||
D is an artificial dimensionless interface, not measured dopamine concentration
|
||||
or the number of accepted DAN spikes. US attempts/rejections and actual events
|
||||
remain in the original runtime artifacts. No resampling compensates for a
|
||||
rejected pulse.
|
||||
|
||||
Fresh neural state is reset each epoch; only the separately authenticated
|
||||
plastic delta carries forward. Original E/U compute the end-of-epoch update,
|
||||
then a separate CPU process recomputes it from sealed actual KC events. Probes
|
||||
have no US, no E/update and no feedback. Brain math is untouched.
|
||||
|
||||
## Readout and gates
|
||||
|
||||
The frozen AQ `learning_gates.py` and original `metrics.py` are pinned before
|
||||
sampling. All six controls, raw signed MBON balance, functional count/latency
|
||||
change, MBON separation and both downstream readouts remain mandatory. The
|
||||
same replicate must satisfy the conjunction; at least three of five pass in
|
||||
each of the eight cells. PAM/PPL or input modes are never pooled to rescue a
|
||||
failure. Original H mean-control rules are reported separately for each DAN
|
||||
control source, both required. Delta change alone cannot imply learning.
|
||||
|
||||
Readout populations are anatomical, never inferred from active/plastic subsets.
|
||||
The original H actual MBON downstream edge table defines legacyDownstream;
|
||||
nonMBONDownstream is its exact set difference with the full MBON population.
|
||||
Missing identity or an altered frozen source stops preparation.
|
||||
|
||||
## Execution, resources and integrity
|
||||
|
||||
Use only the registered 4090 UUID and serial execution. ComfyUI admission must
|
||||
be empty; never stop or evict a service. Source code is committed before
|
||||
registration. Static tables invoke the original L PN-rate transform, preserving
|
||||
all original PN columns for both modes. Shared CS aliases reuse saved input
|
||||
bytes only. The full 63-bit CUDA sampler, full matrix draw and CS window are
|
||||
unchanged; there is no CPU-RNG replacement.
|
||||
|
||||
The engineering ceiling is 256 GiB of new outputs, at least 100 GiB disk reserve,
|
||||
1,800 seconds per child and an absolute 21-day registration deadline. The AQ
|
||||
linear estimate is only planning arithmetic from limited warm measurements,
|
||||
not a measured forecast across all conditions. Exceeding a limit means an
|
||||
incomplete preserved experiment, not shortened trials or changed parameters.
|
||||
|
||||
Each child has an exclusive start record, actual parent-observed exit,
|
||||
dependency hashes and immutable output inventory. A stopped or uncommitted
|
||||
child is never silently retried. A persistent incremental ledger avoids
|
||||
rehashing every historical trial on every iteration; each invocation still
|
||||
rehashes its actual consumed dependencies. Full audits read every unique file
|
||||
and reject missing, extra, changed, linked or incomplete output. They are not
|
||||
claimed to be atomic filesystem snapshots. Mutable compiler cache is accounted
|
||||
separately. CPU/source tests are not described as GPU numerical regression.
|
||||
|
||||
A detached supervisor keeps the serial controller alive across SSH disconnects.
|
||||
Administrative logs live in `/data/digital-drosophila/logs/phase4ar-normal-conditioning/`,
|
||||
outside the immutable per-trial ledger. The final outer auditor must retain
|
||||
these logs and its actual exit receipt. A launch PID alone proves no completion.
|
||||
|
||||
All original event/state/queue/update artifacts are retained; no dense wholebrain
|
||||
time-by-neuron output is added. Complete historical sealed integrity is checked
|
||||
at the boundaries. The five historical reference trials are preserved evidence,
|
||||
not claimed as newly rerun here.
|
||||
|
||||
Normal acquisition is the only authorized scientific scope of this registration.
|
||||
No delayed/reversal/retention assay starts automatically, and no candidate is
|
||||
issued from normal acquisition alone. There is no game, action decoder, RL,
|
||||
visual input, training of base weights, web service or 3D interface.
|
||||
@@ -0,0 +1,442 @@
|
||||
"""Serial, immutable artifact accounting; not a process runner or science gate.
|
||||
|
||||
The long-lived parent hashes this cycle's declared inputs/outputs and the known
|
||||
ledger tail. It does NOT rehash all old artifacts per cycle. Reopening, inspect
|
||||
and final_verify perform full historical verification. Never infer a process's
|
||||
terminal state from a PID, missing file, elapsed time, or a live handle.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from contextlib import contextmanager
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path, PurePosixPath
|
||||
import re
|
||||
import shutil
|
||||
import uuid
|
||||
|
||||
SCHEMA = 'normal-append-ledger-v1'
|
||||
CONTROL = '.append-ledger'
|
||||
REGISTRATION = 'protocol/preregistered.json'
|
||||
SHA = re.compile('[0-9a-f]{64}')
|
||||
ID = re.compile('[A-Za-z0-9][A-Za-z0-9_-]{0,127}')
|
||||
|
||||
|
||||
def require(ok, message):
|
||||
if not ok:
|
||||
raise ValueError(message)
|
||||
|
||||
|
||||
def raw_json(value):
|
||||
return (json.dumps(value, sort_keys=True, separators=(',', ':'), ensure_ascii=False, allow_nan=False)+'\n').encode('utf-8')
|
||||
|
||||
|
||||
def read_json(path):
|
||||
def unique(items):
|
||||
result = {}
|
||||
for key, value in items:
|
||||
require(key not in result, 'Duplicate JSON key'); result[key] = value
|
||||
return result
|
||||
return json.loads(Path(path).read_bytes().decode('utf-8'), object_pairs_hook=unique,
|
||||
parse_constant=lambda _: (_ for _ in ()).throw(ValueError('Nonfinite JSON')))
|
||||
|
||||
|
||||
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 relative_name(value):
|
||||
require(type(value) is str and bool(value) and '\\' not in value and '\x00' not in value and
|
||||
'\n' not in value and '\r' not in value, 'Invalid relative path')
|
||||
path = PurePosixPath(value)
|
||||
require(not path.is_absolute() and str(path) == value and
|
||||
all(p not in ('.', '..', '') and ':' not in p for p in path.parts), 'Escaping/noncanonical path')
|
||||
return value
|
||||
|
||||
|
||||
def unlinked(path):
|
||||
p = Path(path)
|
||||
require(p.is_absolute() and '..' not in p.parts, 'Absolute nonescaping path required')
|
||||
require(not any(q.is_symlink() or (hasattr(q, 'is_junction') and q.is_junction()) for q in (p, *p.parents)),
|
||||
'Linked path forbidden')
|
||||
return p
|
||||
|
||||
|
||||
def identity(path):
|
||||
p = unlinked(path)
|
||||
require(p.is_file(), 'Missing regular file: '+str(p))
|
||||
size = p.stat().st_size; sha = digest(p)
|
||||
require(p.stat().st_size == size, 'File changed while hashing')
|
||||
return dict(bytes=size, sha256=sha)
|
||||
|
||||
|
||||
def validate_identity(value):
|
||||
require(type(value) is dict and set(value) == {'bytes', 'sha256'} and type(value['bytes']) is int and
|
||||
value['bytes'] >= 0 and type(value['sha256']) is str and SHA.fullmatch(value['sha256']), 'Invalid SHA/byte identity')
|
||||
|
||||
|
||||
def _sync_directory(directory):
|
||||
# Windows has no portable directory fsync. File bytes are fsynced there.
|
||||
if os.name != 'nt':
|
||||
descriptor = os.open(directory, os.O_RDONLY)
|
||||
try: os.fsync(descriptor)
|
||||
finally: os.close(descriptor)
|
||||
|
||||
|
||||
def publish_exclusive(path, value):
|
||||
"""Atomic no-replace publication on filesystems supporting hard links.
|
||||
|
||||
No unsafe rename/replace fallback. An interrupted temporary is preserved;
|
||||
inspect/final audit rejects it. A failed destination collision also never
|
||||
deletes or replaces the pre-existing destination.
|
||||
"""
|
||||
path = unlinked(path); require(path.parent.is_dir(), 'Missing publication parent')
|
||||
require(not path.exists(), 'Immutable destination already exists; no retry')
|
||||
raw = raw_json(value); temporary = path.parent / ('.publishing-'+uuid.uuid4().hex)
|
||||
descriptor = os.open(temporary, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600)
|
||||
with os.fdopen(descriptor, 'wb') as stream:
|
||||
stream.write(raw); stream.flush(); os.fsync(stream.fileno())
|
||||
os.link(temporary, path) # Exclusive destination, same bytes/inode; never overwrite.
|
||||
_sync_directory(path.parent)
|
||||
require(path.read_bytes() == raw, 'Published bytes changed')
|
||||
temporary.unlink() # Only this function's exact, newly created temporary.
|
||||
_sync_directory(path.parent)
|
||||
return dict(bytes=len(raw), sha256=hashlib.sha256(raw).hexdigest())
|
||||
|
||||
|
||||
class Ledger:
|
||||
"""One long-lived instance per serial parent, never parallel scheduling.
|
||||
|
||||
Inventories map absolute or root-relative paths to {bytes, sha256}; initial
|
||||
inventory is root-relative and must contain the exact registration file.
|
||||
Call begin BEFORE spawn, then append only after the parent has observed
|
||||
actual exit 0 and saved its independent process receipt. Existing starts
|
||||
are never reissued. An interrupted append may be independently inspected,
|
||||
but automatic resume/rerun is not provided.
|
||||
"""
|
||||
def __init__(self, root, registration_sha, initial_inventory, max_output_bytes, reserve_bytes,
|
||||
shared_build_relative='extension-build'):
|
||||
self.root = unlinked(Path(root)).resolve(strict=True)
|
||||
require(self.root.is_dir(), 'Existing experiment root required')
|
||||
require(type(registration_sha) is str and SHA.fullmatch(registration_sha), 'External registration SHA required')
|
||||
require(type(max_output_bytes) is int and max_output_bytes > 0 and type(reserve_bytes) is int and reserve_bytes >= 0,
|
||||
'Explicit nonnegative reserve and positive output cap required')
|
||||
self.registration_sha = registration_sha; self.max_output_bytes = max_output_bytes; self.reserve_bytes = reserve_bytes
|
||||
self.build_name = relative_name(shared_build_relative)
|
||||
require(self.build_name != CONTROL and not self.build_name.startswith(CONTROL+'/'), 'Build overlaps ledger controls')
|
||||
self.control = self.root / CONTROL; self.header_path = self.control / 'header.json'
|
||||
self.starts = self.control / 'started'; self.entries = self.control / 'entries'
|
||||
require(type(initial_inventory) is dict and initial_inventory, 'Explicit initial inventory required')
|
||||
initial = {}
|
||||
for name, expected in initial_inventory.items():
|
||||
relative_name(name); self._payload_path(name); validate_identity(expected)
|
||||
require(identity(self.root/name) == expected, 'Initial file identity differs: '+name)
|
||||
initial[name] = dict(expected)
|
||||
require(initial.get(REGISTRATION, {}).get('sha256') == registration_sha, 'Initial registration binding missing')
|
||||
header = dict(schema=SCHEMA, root=str(self.root), registration_sha256=registration_sha,
|
||||
initial_inventory=initial, max_output_bytes=max_output_bytes, reserve_bytes=reserve_bytes,
|
||||
shared_mutable_build=self.build_name, initial_inventory_scope='caller supplied; entire tree checked only by final_verify',
|
||||
scientific_gate_claimed=False)
|
||||
if self.header_path.exists():
|
||||
require(read_json(self.header_path) == header, 'Existing ledger authority/options differ')
|
||||
else:
|
||||
require(not self.control.exists(), 'Partial ledger initialization; no automatic retry')
|
||||
self.control.mkdir(); self.starts.mkdir(); self.entries.mkdir()
|
||||
publish_exclusive(self.header_path, header)
|
||||
self.header_identity = identity(self.header_path); self.initial = initial
|
||||
self._tracked = dict(initial); self._controls = {CONTROL+'/header.json': self.header_identity}
|
||||
self._completed = []; self._completed_set = set(); self._pending = {}; self._tail = None
|
||||
self._immutable_bytes = sum(v['bytes'] for v in initial.values())
|
||||
self._control_bytes = self.header_identity['bytes']
|
||||
self._write_failed = False
|
||||
self._replay()
|
||||
self._budget()
|
||||
|
||||
def _payload_path(self, value):
|
||||
path = Path(value)
|
||||
if not path.is_absolute(): path = self.root / relative_name(str(value))
|
||||
path = unlinked(path)
|
||||
require(path.is_relative_to(self.root), 'Output escapes experiment')
|
||||
rel = path.relative_to(self.root).as_posix(); relative_name(rel)
|
||||
require(rel != CONTROL and not rel.startswith(CONTROL+'/') and rel != self.build_name and
|
||||
not rel.startswith(self.build_name+'/'), 'Immutable payload overlaps controls/shared build')
|
||||
return path, rel
|
||||
|
||||
def _rows(self, mapping, *, output, verified=None):
|
||||
require(type(mapping) is dict, 'Explicit inventory dictionary required')
|
||||
result = []; used = set()
|
||||
for text, expected in mapping.items():
|
||||
validate_identity(expected); p = Path(text)
|
||||
if output: p, rel = self._payload_path(text)
|
||||
else:
|
||||
if not p.is_absolute(): p = self.root / relative_name(str(text))
|
||||
p = unlinked(p); rel = p.relative_to(self.root).as_posix() if p.is_relative_to(self.root) else None
|
||||
p = p.resolve(strict=True)
|
||||
rel = p.relative_to(self.root).as_posix() if p.is_relative_to(self.root) else None
|
||||
require(str(p) not in used, 'Duplicate path aliases'); used.add(str(p))
|
||||
if not output and rel in self._tracked:
|
||||
require(expected == self._tracked[rel], 'Consumed immutable input differs from committed identity')
|
||||
observed = self._identity_once(p, verified)
|
||||
require(observed == expected, 'Actual file SHA/bytes differ: '+str(p))
|
||||
result.append(dict(path=str(p), relative_path=rel, **expected))
|
||||
return sorted(result, key=lambda row: row['path'])
|
||||
|
||||
@staticmethod
|
||||
def _identity_once(path, verified):
|
||||
"""One *invocation-local* actual SHA read per unique file, no stat cache."""
|
||||
if verified is None: return identity(path)
|
||||
key = str(path)
|
||||
if key not in verified: verified[key] = identity(path)
|
||||
return verified[key]
|
||||
|
||||
def _check_tail(self):
|
||||
require(not self._write_failed, 'Previous publication failed; independent inspection required, no automatic retry')
|
||||
require(identity(self.header_path) == self.header_identity, 'Ledger header changed')
|
||||
if self._completed:
|
||||
p = self.entries / f'{len(self._completed):016d}.json'
|
||||
require(identity(p)['sha256'] == self._tail, 'Known ledger tail changed')
|
||||
require(not (self.entries / f'{len(self._completed)+1:016d}.json').exists(), 'Unobserved appended entry; independently reopen/inspect')
|
||||
|
||||
@contextmanager
|
||||
def _writer(self):
|
||||
lock = self.control/'writer.lock'; token = uuid.uuid4().hex.encode()
|
||||
unlinked(lock)
|
||||
descriptor = os.open(lock, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600)
|
||||
try:
|
||||
with os.fdopen(descriptor, 'wb') as stream: stream.write(token); stream.flush(); os.fsync(stream.fileno())
|
||||
self._check_tail()
|
||||
yield
|
||||
finally:
|
||||
# Do not remove another actor's/stale lock or broadly delete a tree.
|
||||
if lock.is_file() and lock.read_bytes() == token: lock.unlink()
|
||||
|
||||
def _build_inventory(self):
|
||||
root = unlinked(self.root/self.build_name); result = {}
|
||||
if root.exists():
|
||||
require(root.is_dir(), 'Shared build must be a directory')
|
||||
for p in sorted(root.rglob('*')):
|
||||
unlinked(p)
|
||||
if p.is_file(): result[p.relative_to(self.root).as_posix()] = identity(p)
|
||||
else: require(p.is_dir(), 'Nonregular shared build file')
|
||||
return result
|
||||
|
||||
def _budget(self, *, outputs=(), extra_control=0):
|
||||
# O(new outputs), not O(all previous payload rows), for the serial path.
|
||||
added = {row['relative_path']:row['bytes'] for row in outputs}
|
||||
provisional = {}
|
||||
for attempt in self._pending.values():
|
||||
job = attempt['job']; rel = job['relative_path']
|
||||
if rel is not None and rel not in self._tracked and rel not in added: provisional[rel] = job['bytes']
|
||||
build = self._build_inventory()
|
||||
immutable = self._immutable_bytes+sum(added.values())
|
||||
control = self._control_bytes+extra_control
|
||||
build_bytes = sum(row['bytes'] for row in build.values())
|
||||
total = immutable+control+build_bytes+sum(provisional.values())
|
||||
require(total <= self.max_output_bytes, 'Tracked outputs/control/shared build exceed cap')
|
||||
require(shutil.disk_usage(self.root).free >= self.reserve_bytes+extra_control, 'Free-space reserve would be crossed')
|
||||
return dict(immutable_payload_bytes=immutable, ledger_control_bytes=control, shared_mutable_build_bytes=build_bytes,
|
||||
provisional_job_bytes=sum(provisional.values()), total_accounted_bytes=total,
|
||||
shared_mutable_build_inventory=build, unlisted_files_included=False,
|
||||
scope='tracked immutable payload + ledger controls + pending job files + current shared mutable build; unlisted files checked at final audit')
|
||||
|
||||
def begin(self, entry_id, job_file, metadata=None):
|
||||
"""Persist BEFORE spawning; success does not authorize automatic retry."""
|
||||
require(type(entry_id) is str and ID.fullmatch(entry_id), 'Unsafe entry ID')
|
||||
require(metadata is None or type(metadata) is dict, 'Begin metadata must be a JSON dictionary')
|
||||
with self._writer():
|
||||
require(not self._pending, 'Serial ledger has an uncommitted start; do not rerun it')
|
||||
require(entry_id not in self._completed_set and not (self.starts/(entry_id+'.json')).exists(), 'Entry already started/committed; no retry')
|
||||
path = Path(job_file)
|
||||
if not path.is_absolute(): path = self.root / relative_name(str(job_file))
|
||||
rows = self._rows({str(path):identity(path)}, output=False)
|
||||
value = dict(schema=SCHEMA+'-start', entry_id=entry_id, registration_sha256=self.registration_sha,
|
||||
next_sequence=len(self._completed)+1, prev_entry_sha256=self._tail, job=rows[0], metadata=metadata or {},
|
||||
terminal_state='unknown', retry_authorized=False)
|
||||
raw_json(value); self._pending[entry_id] = value
|
||||
try:
|
||||
self._budget(extra_control=len(raw_json(value)))
|
||||
info = publish_exclusive(self.starts/(entry_id+'.json'),value)
|
||||
except BaseException:
|
||||
self._write_failed = True
|
||||
self._pending.pop(entry_id, None); raise
|
||||
self._controls[f'{CONTROL}/started/{entry_id}.json'] = info
|
||||
self._control_bytes += info['bytes']
|
||||
return dict(entry_id=entry_id,start_sha256=info['sha256'],sequence=value['next_sequence'],terminal_state='unknown',retry_authorized=False)
|
||||
|
||||
def append(self, entry_id, inputs, outputs, metadata):
|
||||
"""Commit exactly one observed-successful serial parent job.
|
||||
|
||||
metadata requires job_file/process_receipt_file/scope/observed_returncode.
|
||||
The independent parent process JSON must declare entry_id, registration
|
||||
SHA, job SHA, complete=true, exit_code integer 0, timed_out=false,
|
||||
exit_observed_by_parent=true. These are authenticated recorded facts,
|
||||
not a new OS observation by this ledger.
|
||||
"""
|
||||
require(type(metadata) is dict and all(k in metadata for k in
|
||||
('job_file','process_receipt_file','scope','observed_returncode')), 'Complete parent metadata required')
|
||||
require(type(metadata['scope']) is str and bool(metadata['scope'].strip()) and
|
||||
type(metadata['observed_returncode']) is int and metadata['observed_returncode'] == 0,
|
||||
'Live/failed process cannot be committed as successful')
|
||||
raw_json(metadata)
|
||||
with self._writer():
|
||||
require(entry_id in self._pending and entry_id not in self._completed_set, 'No unique uncommitted start; no retry')
|
||||
start = self._pending[entry_id]; startfile = self.starts/(entry_id+'.json')
|
||||
require(identity(startfile) == self._controls[f'{CONTROL}/started/{entry_id}.json'] and read_json(startfile) == start,
|
||||
'Start authority changed')
|
||||
incoming = self._rows(inputs, output=False); outgoing = self._rows(outputs, output=True)
|
||||
require(outgoing, 'Empty completed output inventory')
|
||||
require(all(row['relative_path'] not in self._tracked for row in outgoing), 'Output overwrites previously tracked file')
|
||||
self._receipt(entry_id,start,incoming,outgoing,metadata)
|
||||
cumulative = self._immutable_bytes+sum(row['bytes'] for row in outgoing)
|
||||
budget = self._budget(outputs=outgoing)
|
||||
value = dict(schema=SCHEMA+'-entry', sequence=len(self._completed)+1, entry_id=entry_id,
|
||||
registration_sha256=self.registration_sha, prev_entry_sha256=self._tail,
|
||||
start_sha256=identity(startfile)['sha256'], consumed_inputs=incoming, new_outputs=outgoing,
|
||||
metadata=metadata, cumulative_immutable_bytes=cumulative, shared_mutable_build=budget['shared_mutable_build_inventory'],
|
||||
hash_scope='actual declared files and current head; historical payload is rehashed at inspect/reopen/final_verify',
|
||||
scientific_gate_claimed=False, OS_exit_independently_observed_here=False)
|
||||
budget = self._budget(outputs=outgoing,extra_control=len(raw_json(value)))
|
||||
require(budget['shared_mutable_build_inventory'] == value['shared_mutable_build'], 'Shared build changed during append accounting')
|
||||
try: info = publish_exclusive(self.entries/f'{value["sequence"]:016d}.json',value)
|
||||
except BaseException:
|
||||
self._write_failed = True; raise
|
||||
self._controls[f'{CONTROL}/entries/{value["sequence"]:016d}.json'] = info
|
||||
self._control_bytes += info['bytes']; self._immutable_bytes = cumulative
|
||||
self._tracked.update({r['relative_path']:{k:r[k] for k in ('bytes','sha256')} for r in outgoing})
|
||||
self._completed.append(entry_id); self._completed_set.add(entry_id); self._pending.pop(entry_id); self._tail = info['sha256']
|
||||
return dict(sequence=value['sequence'],entry_id=entry_id,entry_sha256=self._tail,
|
||||
cumulative_immutable_bytes=cumulative,budget=budget,scientific_gate_claimed=False)
|
||||
|
||||
def _receipt(self,entry_id,start,inputs,outputs,metadata):
|
||||
def path(value):
|
||||
p=Path(value)
|
||||
return str(unlinked(p if p.is_absolute() else self.root/relative_name(str(value))))
|
||||
jobpath=path(metadata['job_file']);receiptpath=path(metadata['process_receipt_file'])
|
||||
supplied={r['path']:r for r in inputs+outputs}
|
||||
require(jobpath == start['job']['path'] and jobpath in supplied and
|
||||
all(supplied[jobpath][k] == start['job'][k] for k in ('bytes','sha256')), 'Job not bound to original start')
|
||||
require(type(metadata.get('observed_returncode')) is int and metadata['observed_returncode'] == 0 and
|
||||
type(metadata.get('scope')) is str and bool(metadata['scope'].strip()), 'Invalid parent observation/scope')
|
||||
require(receiptpath in {r['path'] for r in outputs}, 'Parent process receipt must be a new output')
|
||||
receipt=read_json(receiptpath)
|
||||
require(receipt.get('entry_id') == entry_id and receipt.get('registration_sha256') == self.registration_sha and
|
||||
receipt.get('job_sha256') == start['job']['sha256'] and receipt.get('complete') is True and
|
||||
type(receipt.get('exit_code')) is int and receipt['exit_code'] == 0 and receipt.get('timed_out') is False and
|
||||
receipt.get('exit_observed_by_parent') is True, 'Missing bound observed-successful parent process receipt')
|
||||
|
||||
def _replay(self, verified=None):
|
||||
verified = {} if verified is None else verified
|
||||
header_observed = identity(self.header_path)
|
||||
require(header_observed == self.header_identity, 'Ledger header changed')
|
||||
verified[str(self.header_path)] = header_observed
|
||||
if self._completed:
|
||||
require(identity(self.entries/f'{len(self._completed):016d}.json')['sha256'] == self._tail,
|
||||
'Previously observed ledger head changed')
|
||||
require(not (self.control/'writer.lock').exists(), 'Writer/stale lock present; state unknown, never clear automatically')
|
||||
tracked=dict(self.initial);controls={CONTROL+'/header.json':self.header_identity};completed=[];completed_set=set();tail=None
|
||||
cumulative=sum(v['bytes'] for v in tracked.values())
|
||||
starts={}
|
||||
require(self.starts.is_dir() and self.entries.is_dir(), 'Missing ledger directories')
|
||||
for p in sorted(self.starts.iterdir()):
|
||||
unlinked(p);require(p.is_file() and p.suffix=='.json' and ID.fullmatch(p.stem), 'Unknown/partial start artifact')
|
||||
row=read_json(p);require(row.get('schema')==SCHEMA+'-start' and row.get('entry_id')==p.stem and
|
||||
row.get('registration_sha256')==self.registration_sha and row.get('retry_authorized') is False,
|
||||
'Invalid start schema/authority')
|
||||
require(row['job']==self._rows({row['job']['path']:{k:row['job'][k] for k in ('bytes','sha256')}},output=False,verified=verified)[0], 'Start job bytes changed')
|
||||
starts[p.stem]=row;controls[p.relative_to(self.root).as_posix()]=self._identity_once(p,verified)
|
||||
for index,p in enumerate(sorted(self.entries.iterdir()),1):
|
||||
unlinked(p);require(p.is_file() and p.name==f'{index:016d}.json','Missing/out-of-order/temporary ledger entry')
|
||||
row=read_json(p);entry_id=row.get('entry_id');require(entry_id in starts and entry_id not in completed_set,'Missing/duplicate start binding')
|
||||
start=starts[entry_id]
|
||||
require(row.get('schema')==SCHEMA+'-entry' and type(row.get('sequence')) is int and row['sequence']==index and
|
||||
row.get('registration_sha256')==self.registration_sha and row.get('prev_entry_sha256')==tail and
|
||||
start['next_sequence']==index and start['prev_entry_sha256']==tail and
|
||||
row['start_sha256']==controls[f'{CONTROL}/started/{entry_id}.json']['sha256'] and
|
||||
row.get('scientific_gate_claimed') is False,'Entry chain/start identity differs')
|
||||
for field,output in (('consumed_inputs',False),('new_outputs',True)):
|
||||
items=row[field];require(type(items) is list and len({r['path'] for r in items})==len(items),'Invalid stored file rows')
|
||||
observed=self._rows({r['path']:{k:r[k] for k in ('bytes','sha256')} for r in items},output=output,verified=verified)
|
||||
require(items==observed,'Stored absolute/relative/hash identity differs')
|
||||
require(row['new_outputs'] and all(r['relative_path'] not in tracked for r in row['new_outputs']), 'Immutable output repeated')
|
||||
self._receipt(entry_id,start,row['consumed_inputs'],row['new_outputs'],row['metadata'])
|
||||
tracked.update({r['relative_path']:{k:r[k] for k in ('bytes','sha256')} for r in row['new_outputs']})
|
||||
cumulative+=sum(r['bytes'] for r in row['new_outputs'])
|
||||
require(type(row['cumulative_immutable_bytes']) is int and row['cumulative_immutable_bytes']==cumulative,'Cumulative byte accounting differs')
|
||||
completed.append(entry_id);completed_set.add(entry_id);info=self._identity_once(p,verified);controls[p.relative_to(self.root).as_posix()]=info;tail=info['sha256']
|
||||
pending={k:v for k,v in starts.items() if k not in completed_set}
|
||||
require(len(pending)<=1 and all(v['next_sequence']==len(completed)+1 and v['prev_entry_sha256']==tail for v in pending.values()),
|
||||
'Uncommitted start does not follow actual head')
|
||||
for name,info in tracked.items():require(self._identity_once(self.root/name,verified)==info,'Historical payload changed: '+name)
|
||||
allowed=set(controls)
|
||||
for p in self.control.rglob('*'):
|
||||
unlinked(p)
|
||||
require(p.is_dir() or (p.is_file() and p.relative_to(self.root).as_posix() in allowed),'Unlisted/partial ledger control artifact')
|
||||
# Fresh head reads bracket this audit. This is not an atomic FS snapshot.
|
||||
require(identity(self.header_path)==self.header_identity,'Ledger header changed during audit')
|
||||
require(not (self.control/'writer.lock').exists() and not (self.entries/f'{len(completed)+1:016d}.json').exists(),
|
||||
'Concurrent writer/append detected; audit not terminal')
|
||||
if completed:require(identity(self.entries/f'{len(completed):016d}.json')['sha256']==tail,'Ledger head changed during audit')
|
||||
self._tracked=tracked;self._controls=controls;self._completed=completed;self._completed_set=completed_set;self._pending=pending;self._tail=tail
|
||||
self._immutable_bytes=cumulative
|
||||
self._control_bytes=sum(v['bytes'] for v in controls.values())
|
||||
|
||||
def inspect(self):
|
||||
"""Full historical read verification; no restart or retry authorization."""
|
||||
self._replay()
|
||||
return dict(schema=SCHEMA+'-inspection',registration_sha256=self.registration_sha,entries=len(self._completed),
|
||||
entry_ids=list(self._completed),head_sha256=self._tail,uncommitted_entry_ids=sorted(self._pending),
|
||||
uncommitted_state='STARTED-UNCOMMITTED-STATE-UNKNOWN' if self._pending else None,
|
||||
retry_authorized=False,all_tracked_history_rehashed=True,entire_experiment_tree_checked=False,
|
||||
SHA_scope='each unique payload path read during this invocation; no cross-invocation cache; not an atomic snapshot',
|
||||
budget=self._budget(),scientific_gate_claimed=False)
|
||||
|
||||
def final_verify(self,expected_entry_ids):
|
||||
"""Full tree at this instant, before caller writes any future final report.
|
||||
|
||||
expected IDs must be derived by caller from the externally pinned
|
||||
registration. Shared build is mutable and separately hashed/accounted,
|
||||
never silently accepted as an immutable payload.
|
||||
"""
|
||||
require(type(expected_entry_ids) is list and all(type(x) is str and ID.fullmatch(x) for x in expected_entry_ids) and
|
||||
len(set(expected_entry_ids))==len(expected_entry_ids),'Exact registered expected entry order required')
|
||||
errors=[];verified={}
|
||||
try:self._replay(verified)
|
||||
except (ValueError,OSError,KeyError,TypeError) as exc:errors.append(type(exc).__name__+': '+str(exc))
|
||||
expected={**self._tracked,**self._controls};actual={};links=[]
|
||||
for p in sorted(self.root.rglob('*')):
|
||||
rel=p.relative_to(self.root).as_posix()
|
||||
try:
|
||||
unlinked(p)
|
||||
if p.is_file():actual[rel]=self._identity_once(p,verified)
|
||||
else:require(p.is_dir(),'Nonregular artifact')
|
||||
except (ValueError,OSError) as exc:links.append(rel);errors.append(str(exc))
|
||||
build={k:v for k,v in actual.items() if k.startswith(self.build_name+'/')}
|
||||
immutable={k:v for k,v in actual.items() if k not in build}
|
||||
extra=sorted(set(immutable)-set(expected));missing=sorted(set(expected)-set(immutable))
|
||||
changed=sorted(k for k in set(expected)&set(immutable) if expected[k]!=immutable[k])
|
||||
exact_order=self._completed==expected_entry_ids
|
||||
actual_bytes=sum(v['bytes'] for v in actual.values());within_cap=actual_bytes<=self.max_output_bytes
|
||||
free_reserve=shutil.disk_usage(self.root).free>=self.reserve_bytes
|
||||
# Bracket the *entire* tree walk as well as replay. These fresh small
|
||||
# authority reads deliberately bypass the per-invocation payload cache.
|
||||
# They detect changed/appended heads, not an atomic filesystem snapshot.
|
||||
try:
|
||||
self._check_tail()
|
||||
require(not (self.control/'writer.lock').exists(), 'Concurrent writer detected at final audit end')
|
||||
except (ValueError,OSError) as exc:errors.append(type(exc).__name__+': '+str(exc))
|
||||
passed=not(errors or extra or missing or changed or self._pending) and exact_order and within_cap and free_reserve
|
||||
return dict(schema=SCHEMA+'-final-audit',pass_all=passed,registration_sha256=self.registration_sha,
|
||||
entry_ids=list(self._completed),expected_entry_ids=expected_entry_ids,expected_order_exact=exact_order,
|
||||
head_sha256=self._tail,extra_files=extra,missing_files=missing,changed_files=changed,unsafe_files=links,errors=errors,
|
||||
uncommitted_entry_ids=sorted(self._pending),uncommitted_state_unknown=bool(self._pending),retry_authorized=False,
|
||||
actual_total_bytes=actual_bytes,immutable_and_ledger_bytes=actual_bytes-sum(v['bytes'] for v in build.values()),
|
||||
shared_mutable_build_bytes=sum(v['bytes'] for v in build.values()),shared_mutable_build_inventory=build,
|
||||
output_cap_respected=within_cap,free_reserve_respected=free_reserve,
|
||||
all_current_files_rehashed=True,checked_before_future_final_report=True,
|
||||
SHA_scope='each unique path read during this invocation; fresh header/head checks bracket full audit; no cross-invocation cache; not an atomic snapshot',
|
||||
expected_inventory_authority='caller derives IDs from pinned registration; ledger does not interpret scientific plan',
|
||||
scientific_gate_claimed=False)
|
||||
@@ -0,0 +1,131 @@
|
||||
"""Exact frozen L rate transform and full-shape CUDA sampler, no brain/update.
|
||||
|
||||
Static table derivation is CPU/read-only. Sampling is a separate explicit job.
|
||||
Common-random aliases share only saved immutable CS bytes, never brain outputs.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import argparse
|
||||
import os
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import time
|
||||
import numpy as np
|
||||
from normal_io import *
|
||||
|
||||
PINS = {
|
||||
'conditioning_inputs.py': '19382e066e450140bb653a3661f980ffe7cc62f412020ef57df0b6e6b3cbb8ba',
|
||||
'conditioning_preflight_inputs.py': '846d2141b472f18b1bb728eed4aa33876896d4b33dece364787c81204f62995f',
|
||||
'trial_plan.py': '6fed3f494d075339a7e5b001d43b2598640b189e038952fbd4d41200bacac587',
|
||||
'seed_registry.py': '0da033b132095ec3087b5d9f64e53c2e391fa50ab0b7653b31296eeb84799b7e',
|
||||
}
|
||||
|
||||
def dependencies():
|
||||
verify({str(LAB/n): s for n,s in PINS.items()})
|
||||
require(not any(n in sys.modules for n in ('runtime_light','conditioning_epoch')), 'No neural modules in sampler')
|
||||
sys.path.insert(0, str(LAB))
|
||||
import conditioning_preflight_inputs as source
|
||||
import conditioning_inputs as inputs
|
||||
require(Path(source.__file__) == LAB/'conditioning_preflight_inputs.py' and
|
||||
Path(inputs.__file__) == LAB/'conditioning_inputs.py', 'Wrong input module identity')
|
||||
return source, inputs
|
||||
|
||||
def derive_rates(root=ROOT):
|
||||
"""Calls the original pinned pn_drive for both registered modes."""
|
||||
import pandas as pd
|
||||
import yaml
|
||||
source, inputs = dependencies()
|
||||
loaded = source.load_rate_tables(root)
|
||||
static = Path(root)/source.STATIC
|
||||
selection = read(static/'odor-encoder/selection.json')
|
||||
panel = pd.read_parquet(static/'odor-encoder/frozen-odor-panel.parquet')
|
||||
mapping = pd.read_parquet(static/'receptor-mapping/olfactory-mapping.parquet')
|
||||
config = yaml.safe_load((Path(root)/source.CONFIG_REL).read_text())
|
||||
drive, ast_sha = source._extract_drive((Path(root)/source.SOURCE_REL).read_bytes(), str(Path(root)/source.SOURCE_REL))
|
||||
vectors = npz(static/'odor-encoder/mapped-glomerular-vectors.npz')
|
||||
result = {}
|
||||
for mode in ('physiological','matched_energy'):
|
||||
for cue in ('A','B'):
|
||||
original = loaded['tables'][cue]
|
||||
targets, rates, frame = drive(original['odor_id'], vectors[original['odor_id']], mapping,
|
||||
selection['glomeruli_order'], mode, loaded['audit']['median_mapped_response_sum'], config)
|
||||
inputs.probabilities_f32(targets, rates)
|
||||
require(np.array_equal(frame.neuron_idx.to_numpy(np.int32), targets) and
|
||||
frame.rate_hz.to_numpy(np.float32).tobytes() == rates.tobytes(), 'Original PN order differs')
|
||||
if mode == 'physiological':
|
||||
require(all(original[n].tobytes() == a.tobytes() for n,a in (('targets',targets),('rates_hz',rates))),
|
||||
'Physiological reconstruction differs')
|
||||
prior = npz(Path(root)/f'experiments/phase4ao-conditioning-interface/inputs/static/{cue}-rates.npz')
|
||||
require(all(prior[n].dtype == a.dtype and prior[n].shape == a.shape and prior[n].tobytes() == a.tobytes()
|
||||
for n,a in (('targets',targets),('rates_hz',rates))), 'Prior AO rate bytes differ')
|
||||
result[mode+'--'+cue] = dict(targets=targets, rates_hz=rates)
|
||||
verify({str(Path(root)/p):s for p,s in source.SOURCE_PINS.items()})
|
||||
return result, dict(original_source_sha256=source.SOURCE_PINS, original_AST_sha256=ast_sha,
|
||||
physiological_matches_original_AO=True, original_PN_column_order_preserved=True,
|
||||
modes=['physiological','matched_energy'], clipping=False, gain_tuning=False,
|
||||
historical_dynamic_results_read=False, random_draws=0)
|
||||
|
||||
def descriptor(task):
|
||||
r = task['recipe']
|
||||
require(task['steps'] == 1200 and task['mode'] in ('physiological','matched_energy'), 'Wrong normal clock/mode')
|
||||
if task['kind'] == 'train':
|
||||
cs = r['cs']
|
||||
if cs is None: return None
|
||||
cue, seed, start, stop = cs['cue'],cs['seed'],cs['start_tick'],cs['stop_tick_exclusive']
|
||||
stream = cs['source_stream_id']
|
||||
else:
|
||||
require(task['kind'] == 'probe' and r['US_requested'] is False and r['weight_updates_enabled'] is False,
|
||||
'Probe contains US/update')
|
||||
cue, seed = r['cue'], r['input']['seed']
|
||||
start, stop, stream = r['cs_start_tick'], r['cs_stop_tick_exclusive'], r['input']['stream_id']
|
||||
require(cue in ('A','B') and type(seed) is int and 0 <= seed < 2**63 and (start,stop) == (0,1000),
|
||||
'CS timing/full seed differs')
|
||||
return dict(mode=task['mode'],cue=cue,seed=seed,steps=1200,cs_start_tick=start,cs_stop_tick_exclusive=stop,
|
||||
source_stream_id=stream,table_id=task['mode']+'--'+cue)
|
||||
|
||||
def inventory_from_plan(plan):
|
||||
descriptors, task_inputs = {}, {}
|
||||
for task in plan['tasks']:
|
||||
d = descriptor(task)
|
||||
key = None if d is None else content_sha(d)
|
||||
if d is not None:
|
||||
require(key not in descriptors or descriptors[key] == d, 'Conflicting shared CS descriptor')
|
||||
descriptors[key] = d
|
||||
require(task['task_id'] not in task_inputs, 'Duplicate planned task')
|
||||
task_inputs[task['task_id']] = key
|
||||
require(len(descriptors) == 4080, 'Expected 4,000 training + 80 evaluation streams')
|
||||
return dict(schema='normal-CS-input-inventory-v1',descriptors=descriptors,task_inputs=task_inputs,
|
||||
brain_output_deduplication=False,CS_only_saved=True,US_composed_from_each_original_epoch=True)
|
||||
|
||||
def sample(reg_sha):
|
||||
require(sys.dont_write_bytecode, 'Use -B')
|
||||
file = EXP/'protocol/preregistered.json'; require(digest(file) == reg_sha, 'Registration differs')
|
||||
reg = read(file); verify(reg['source_sha256']); verify(reg['static_input_sha256'])
|
||||
require(reg['scientific_scope'] == 'normal-acquisition-only', 'Wrong scientific scope')
|
||||
out = unlinked(EXP/'inputs/generated'); require(not out.exists(), 'Sampler cannot retry existing output')
|
||||
h = load_source('_normal_sampler_admission', AP/'isolated_workers.py', AP_SHA)
|
||||
os.environ['CUDA_VISIBLE_DEVICES'] = GPU
|
||||
admission = h._admit_brain()
|
||||
source, inputs = dependencies()
|
||||
inv = read(EXP/'protocol/input-inventory.json')
|
||||
require(digest(EXP/'protocol/input-inventory.json') == reg['prepared_sha256'][str(EXP/'protocol/input-inventory.json')],
|
||||
'Input inventory differs')
|
||||
out.mkdir(); start = time.perf_counter(); completed = {}
|
||||
for index,(key,d) in enumerate(inv['descriptors'].items()):
|
||||
if index % 100 == 0: h._admit_brain()
|
||||
table = npz(EXP/f"inputs/static/{d['table_id']}.npz")
|
||||
require(digest(EXP/f"inputs/static/{d['table_id']}.npz") ==
|
||||
reg['prepared_sha256'][str(EXP/f"inputs/static/{d['table_id']}.npz")], 'Rate file changed')
|
||||
result = inputs.generate_cs_requests(table['targets'],table['rates_hz'],seed=d['seed'],steps=1200,
|
||||
cs_start_tick=0,cs_stop_tick=1000,device='cuda:0',max_uniform_draws=reg['budget']['max_uniform_draws'])
|
||||
save_npz(out/(key+'.npz'),result['requests'])
|
||||
save(out/(key+'.json'),dict(descriptor=d,audit=result['audit'],requests_sha256=digest(out/(key+'.npz'))))
|
||||
completed[key] = dict(requests=pin(out/(key+'.npz')),audit=pin(out/(key+'.json')))
|
||||
verify(reg['source_sha256']); verify(reg['static_input_sha256'])
|
||||
save(EXP/'receipts/input-generation.json',dict(complete=True,registration_sha256=reg_sha,
|
||||
input_inventory_sha256=digest(EXP/'protocol/input-inventory.json'),inputs=completed,
|
||||
descriptors=len(completed),wall_seconds=time.perf_counter()-start,admission=admission,
|
||||
brain_executed=False,weight_updates_executed=False))
|
||||
|
||||
if __name__ == '__main__':
|
||||
p=argparse.ArgumentParser();p.add_argument('--registration-sha256',required=True)
|
||||
sample(p.parse_args().registration_sha256)
|
||||
@@ -0,0 +1,88 @@
|
||||
"""Small exclusive file helpers. No neural imports, mutation or retry policy."""
|
||||
from __future__ import annotations
|
||||
import hashlib
|
||||
import importlib.util
|
||||
import json
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
ROOT = Path('/data/digital-drosophila')
|
||||
MODEL = Path(__file__).resolve().parent
|
||||
LAB = MODEL.parent/'olfactory-conditioning-lab-v1'
|
||||
AQ = MODEL.parent/'conditioning-execution-v1'
|
||||
AP = MODEL.parent/'conditioning-interface-v2'
|
||||
EXP = ROOT/'experiments/phase4ar-normal-conditioning'
|
||||
GPU = 'GPU-79f3a85d-adce-7833-7003-6488140ca596'
|
||||
AP_SHA = 'e47651a8ea99d7c44115107ff6b5dc71312183609ae11c891db65bb21ed61e30'
|
||||
|
||||
def require(ok, message):
|
||||
if not ok: raise ValueError(message)
|
||||
|
||||
def digest(path):
|
||||
h = hashlib.sha256()
|
||||
with Path(path).open('rb') as f:
|
||||
for data in iter(lambda: f.read(8 << 20), b''): h.update(data)
|
||||
return h.hexdigest()
|
||||
|
||||
def canonical(value):
|
||||
return json.dumps(value, sort_keys=True, separators=(',', ':'), ensure_ascii=False, allow_nan=False)
|
||||
|
||||
def content_sha(value):
|
||||
return hashlib.sha256(canonical(value).encode()).hexdigest()
|
||||
|
||||
def read(path):
|
||||
def pairs(items):
|
||||
result = {}
|
||||
for key, value in items:
|
||||
require(key not in result, 'Duplicate JSON key'); result[key] = value
|
||||
return result
|
||||
return json.loads(Path(path).read_text(encoding='utf-8'), object_pairs_hook=pairs,
|
||||
parse_constant=lambda _: (_ for _ in ()).throw(ValueError('Nonfinite JSON')))
|
||||
|
||||
def save(path, value):
|
||||
with unlinked(path).open('x', encoding='utf-8', newline='\n') as f:
|
||||
json.dump(value, f, sort_keys=True, indent=2, ensure_ascii=False, allow_nan=False); f.write('\n')
|
||||
|
||||
def unlinked(path):
|
||||
p = Path(path)
|
||||
require(p.is_absolute() and '..' not in p.parts and not any(x.is_symlink() or
|
||||
(hasattr(x, 'is_junction') and x.is_junction()) for x in (p, *p.parents)), 'Unsafe linked path')
|
||||
return p
|
||||
|
||||
def identity(path):
|
||||
p = unlinked(path); require(p.is_file(), 'Missing regular file: '+str(p))
|
||||
return dict(sha256=digest(p), bytes=p.stat().st_size)
|
||||
|
||||
def pin(path):
|
||||
return dict(path=str(unlinked(path)), sha256=digest(path))
|
||||
|
||||
def verify(pins):
|
||||
for p, sha in pins.items(): require(identity(p)['sha256'] == sha, 'Pinned input changed: '+str(p))
|
||||
|
||||
def inventory(root):
|
||||
result = {}
|
||||
for p in sorted(unlinked(root).rglob('*')):
|
||||
unlinked(p)
|
||||
if p.is_file(): result[str(p)] = identity(p)
|
||||
else: require(p.is_dir(), 'Nonregular artifact')
|
||||
return result
|
||||
|
||||
def load_source(name, path, sha):
|
||||
path = unlinked(path); raw = path.read_bytes()
|
||||
require(hashlib.sha256(raw).hexdigest() == sha and name not in sys.modules, 'Source/module identity differs')
|
||||
spec = importlib.util.spec_from_file_location(name, path); module = importlib.util.module_from_spec(spec)
|
||||
sys.modules[name] = module
|
||||
exec(compile(raw, str(path), 'exec'), module.__dict__)
|
||||
return module
|
||||
|
||||
def npz(path):
|
||||
import numpy as np
|
||||
with np.load(path, allow_pickle=False) as f: return {k: f[k].copy() for k in f.files}
|
||||
|
||||
def save_npz(path, values):
|
||||
import numpy as np
|
||||
with unlinked(path).open('xb') as f: np.savez_compressed(f, **values)
|
||||
|
||||
def task_key(task):
|
||||
# IDs remain verbatim in receipts; filesystem IDs never incorporate slashes.
|
||||
return 'task-'+hashlib.sha256(task['task_id'].encode()).hexdigest()
|
||||
@@ -0,0 +1,528 @@
|
||||
"""Read-only normal analysis, conditional on independent final integrity.
|
||||
|
||||
analyze(exp, registration_sha256, *, verified_inventory, final_ledger) consumes
|
||||
an externally authenticated absolute-path -> {bytes, sha256} inventory and the
|
||||
final append-ledger audit. Neither caller Boolean nor digest alone is treated
|
||||
as an OS observation: actual ledger/start/job/parent/worker receipts and every
|
||||
consumed file are rebound to bytes. SHA caching is invocation-local, never
|
||||
mtime-based. The outer verifier still owns complete tree/historical integrity,
|
||||
anatomical/source authority, concurrency exclusion and the final science claim.
|
||||
No writes, sampling, subprocesses, follow-up assays, candidates or new gates.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from collections import defaultdict
|
||||
import hashlib
|
||||
import io
|
||||
import json
|
||||
from pathlib import Path
|
||||
import types
|
||||
|
||||
import numpy as np
|
||||
|
||||
GATES_SHA256 = '8ae9bcb77fe14dbdda164f86ffdbfc1e2976be752766ef526777577223b4dd99'
|
||||
PLAN_SHA256 = 'd1a6b840a547cb10b00df40f4d8b287867d09f355c9777e5f7a8b9489f5555ea'
|
||||
ARM_NAMES = dict(paired='paired', d_zero='D=0', frozen='frozen', random_reward='random reward',
|
||||
unpaired='unpaired', cs_only='CS-only', dan_only='DAN-only')
|
||||
ODORS = {'A': '4-ethylphenol', 'B': '3-hexanone'}
|
||||
POINTS = (0, 1, 2, 5, 10, 20, 50)
|
||||
|
||||
|
||||
def require(ok, message):
|
||||
if not ok:
|
||||
raise ValueError(message)
|
||||
|
||||
|
||||
def canonical(value):
|
||||
return json.dumps(value, sort_keys=True, separators=(',', ':'), ensure_ascii=False, allow_nan=False)
|
||||
|
||||
|
||||
def sha(value):
|
||||
return hashlib.sha256(canonical(value).encode()).hexdigest()
|
||||
|
||||
|
||||
def _module(name, path, expected):
|
||||
raw = path.read_bytes()
|
||||
require(hashlib.sha256(raw).hexdigest() == expected, 'Analysis dependency pin differs: ' + str(path))
|
||||
module = types.ModuleType(name)
|
||||
module.__file__ = str(path)
|
||||
exec(compile(raw, str(path), 'exec'), module.__dict__)
|
||||
return module
|
||||
|
||||
|
||||
_HERE = Path(__file__).resolve().parent
|
||||
G = _module('_normal_frozen_gates', _HERE.parent / 'conditioning-execution-v1/learning_gates.py', GATES_SHA256)
|
||||
P = _module('_normal_frozen_plan', _HERE / 'normal_plan.py', PLAN_SHA256)
|
||||
M = G.M
|
||||
|
||||
|
||||
class Reader:
|
||||
"""Actual SHA once per unique path per invocation; not an atomic snapshot."""
|
||||
def __init__(self, inventory):
|
||||
require(type(inventory) is dict and inventory, 'Externally verified checksum inventory required')
|
||||
self.inventory = inventory
|
||||
self.seen = {}
|
||||
|
||||
def path(self, path):
|
||||
path = Path(path)
|
||||
require(path.is_absolute() and '..' not in path.parts and not any(p.is_symlink() or
|
||||
(hasattr(p, 'is_junction') and p.is_junction()) for p in (path, *path.parents)), 'Unsafe artifact path')
|
||||
key = str(path)
|
||||
require(key in self.inventory, 'Artifact absent from external checksum authority: ' + key)
|
||||
expected = self.inventory[key]
|
||||
require(type(expected) is dict and set(expected) == {'bytes', 'sha256'} and
|
||||
type(expected['bytes']) is int and expected['bytes'] >= 0 and M._sha(expected['sha256']), 'Invalid checksum authority')
|
||||
return path, expected
|
||||
|
||||
def check(self, path):
|
||||
path, expected = self.path(path)
|
||||
key = str(path)
|
||||
if key not in self.seen:
|
||||
require(path.is_file(), 'Missing artifact: ' + key)
|
||||
digest = hashlib.sha256()
|
||||
size = 0
|
||||
with path.open('rb') as stream:
|
||||
for part in iter(lambda: stream.read(8 << 20), b''):
|
||||
digest.update(part); size += len(part)
|
||||
require(dict(bytes=size, sha256=digest.hexdigest()) == expected, 'Actual file checksum differs: ' + key)
|
||||
self.seen[key] = dict(expected)
|
||||
require(self.seen[key] == expected, 'Checksum authority changed during analysis')
|
||||
return expected
|
||||
|
||||
def raw(self, path):
|
||||
self.check(path)
|
||||
# Parsed data are read from the now-bound file, not retained for every
|
||||
# trajectory. Concurrent mutation remains an outer quiescence obligation.
|
||||
return Path(path).read_bytes()
|
||||
|
||||
def json(self, path):
|
||||
def unique(items):
|
||||
result = {}
|
||||
for key, value in items:
|
||||
require(key not in result, 'Duplicate JSON field'); result[key] = value
|
||||
return result
|
||||
return json.loads(self.raw(path).decode('utf-8'), object_pairs_hook=unique,
|
||||
parse_constant=lambda _: (_ for _ in ()).throw(ValueError('Nonfinite JSON')))
|
||||
|
||||
def arrays(self, path):
|
||||
with np.load(io.BytesIO(self.raw(path)), allow_pickle=False) as archive:
|
||||
return {key: archive[key].copy() for key in archive.files}
|
||||
|
||||
|
||||
def task_key(task):
|
||||
return 'task-' + hashlib.sha256(task['task_id'].encode()).hexdigest()
|
||||
|
||||
|
||||
def expected_entries(plan):
|
||||
result = ['input-generation']
|
||||
for task in plan['tasks']:
|
||||
result.extend(task_key(task) + suffix for suffix in
|
||||
(('--brain', '--update', '--verify') if task['kind'] == 'train' else ('--brain',)))
|
||||
return result
|
||||
|
||||
|
||||
def audit_case(reader, exp, task, job, *, template, inputs, sampler, populations, population_file, output_cap):
|
||||
"""Independent raw CS/US composition and reset/spec checks; no brain call.
|
||||
|
||||
A scheduled US request is not an accepted spike or a successful behavior.
|
||||
The artificial D scalar remains the original recipe, never an event count.
|
||||
"""
|
||||
exp = Path(exp); case = exp / 'cases' / task_key(task)
|
||||
require(job['case_dir'] == str(case), 'Case path differs from original task')
|
||||
spec = reader.json(case / 'spec.json')
|
||||
removed = ('validation_cohort', 'odor_index', 'expected_external_events', 'training', 'cs_input_seed', 'cs_input_seed_bits',
|
||||
'seed_scope', 'odor_id', 'odor_name', 'source_panel_row', 'source_panel_split', 'rate_sum_hz', 'target_count',
|
||||
'expected_CS_requests', 'CS_window', 'outer_epoch_id', 'outer_arm', 'outer_protocol')
|
||||
fixed = {k: v for k, v in template.items() if k not in removed}
|
||||
fixed.update(name=task_key(task), steps=1200, duration_ms=120., max_steps=1200, budget_root=str(exp),
|
||||
output_budget_bytes=output_cap, mode=task['mode'], within_trial_weight_updates=False,
|
||||
outer_protocol='normal-acquisition-v1', outer_task_id=task['task_id'], outer_arm=task['arm'])
|
||||
require(canonical(spec) == canonical(fixed) and spec['seed'] == template['seed'] and spec['dt_ms'] == .1 and
|
||||
spec['apl_delay_steps'] == 18 and spec['precision'] == 'float64' and spec['apl_precision'] == 'float32' and
|
||||
spec['record_history'] is False and spec['kind'] == 'fullgraph', 'Scientific model/reset/clock spec changed')
|
||||
recipe = task['recipe']
|
||||
cs_recipe = recipe['cs'] if task['kind'] == 'train' else recipe
|
||||
expected = None
|
||||
if cs_recipe is not None:
|
||||
cue = cs_recipe['cue']
|
||||
seed = cs_recipe['seed'] if task['kind'] == 'train' else cs_recipe['input']['seed']
|
||||
stream = cs_recipe['source_stream_id'] if task['kind'] == 'train' else cs_recipe['input']['stream_id']
|
||||
require(type(seed) is int and 0 <= seed < 2**63, 'Original full63 seed required')
|
||||
expected = dict(mode=task['mode'], cue=cue, seed=seed, steps=1200, cs_start_tick=0,
|
||||
cs_stop_tick_exclusive=1000, source_stream_id=stream, table_id=task['mode'] + '--' + cue)
|
||||
csid = None if expected is None else sha(expected)
|
||||
require(inputs['task_inputs'][task['task_id']] == csid, 'Original task/CS descriptor mapping differs')
|
||||
binding = reader.json(case / 'input-binding.json')
|
||||
require(binding['task_id'] == task['task_id'] and binding['CS_descriptor_id'] == csid and
|
||||
binding['DAN_type'] == task['dan_type'] and binding['population_file'] ==
|
||||
dict(path=population_file, sha256=reader.check(population_file)['sha256']), 'Case input/population binding differs')
|
||||
empty = dict(tick=np.empty(0, np.int32), neuron_idx=np.empty(0, np.int32))
|
||||
source = empty
|
||||
if csid is None:
|
||||
require(binding['CS_source'] is None, 'No-CS epoch acquired an odor source')
|
||||
else:
|
||||
npzpath = exp / f'inputs/generated/{csid}.npz'; jsonpath = exp / f'inputs/generated/{csid}.json'
|
||||
generated = reader.json(jsonpath); audit = generated['audit']
|
||||
require(inputs['descriptors'][csid] == generated['descriptor'] == expected and
|
||||
generated['requests_sha256'] == reader.check(npzpath)['sha256'] and
|
||||
binding['CS_source'] == dict(path=str(npzpath), sha256=reader.check(npzpath)['sha256']) and
|
||||
sampler['inputs'][csid] == dict(requests=binding['CS_source'], audit=dict(path=str(jsonpath), sha256=reader.check(jsonpath)['sha256'])),
|
||||
'Saved sampler receipt/descriptor differs')
|
||||
require(audit['seed'] == audit['generator_initial_seed'] == seed and audit['seed_bits'] == 63 and
|
||||
audit['seed_conversion'] == 'exact integer; no truncation/modulo/offset' and audit['private_generator'] is True and
|
||||
audit['matrix_draw_calls'] == 1 and audit['uniform_matrix_shape'][0] == 1200 and audit['CS_window'] == [0, 1000],
|
||||
'Original sampler seed/full-shape/window evidence differs')
|
||||
source = reader.arrays(npzpath)
|
||||
|
||||
def keys(request):
|
||||
require(set(request) == {'tick', 'neuron_idx'} and all(v.dtype == np.int32 and v.ndim == 1 for v in request.values()) and
|
||||
request['tick'].shape == request['neuron_idx'].shape and np.all((request['tick'] >= 0) & (request['tick'] < 1200)) and
|
||||
np.all((request['neuron_idx'] >= 0) & (request['neuron_idx'] < 166700)), 'Invalid raw request arrays')
|
||||
result = request['tick'].astype(np.int64) * 166700 + request['neuron_idx']
|
||||
require(np.all(result[1:] > result[:-1]), 'Requests are not sorted unique')
|
||||
return result
|
||||
|
||||
source_keys = keys(source)
|
||||
require(np.all(source['tick'] < 1000), 'CS escaped original window')
|
||||
cs, us, combined = (reader.arrays(case / name) for name in ('cs_requests.npz', 'us_requests.npz', 'requests.npz'))
|
||||
cs_keys, us_keys, combined_keys = keys(cs), keys(us), keys(combined)
|
||||
require(np.array_equal(source_keys, cs_keys), 'Actual case CS differs from original saved input')
|
||||
requested = task['kind'] == 'train' and recipe['us']['requested']
|
||||
dan = populations[task['dan_type']]
|
||||
require(dan.dtype == np.int32 and dan.ndim == 1 and np.all(dan[1:] > dan[:-1]), 'Actual DAN mapping differs')
|
||||
require(binding['DAN_membership_sha256'] == hashlib.sha256(dan.tobytes()).hexdigest(), 'DAN membership binding differs')
|
||||
expected_us = 900 * 166700 + dan.astype(np.int64) if requested else np.empty(0, np.int64)
|
||||
require(np.array_equal(us_keys, expected_us) and not np.intersect1d(cs_keys, us_keys).size and
|
||||
np.array_equal(combined_keys, np.union1d(cs_keys, us_keys)), 'Actual scheduled US/CS composition differs')
|
||||
masks = reader.arrays(case / 'source-mask.npz')
|
||||
expected_mask = np.where(np.isin(combined_keys, cs_keys), 1, 2).astype(np.uint8)
|
||||
require(set(masks) == {'source_mask'} and masks['source_mask'].dtype == np.uint8 and
|
||||
np.array_equal(masks['source_mask'], expected_mask) and binding['composition']['policy'] == 'error' and
|
||||
binding['composition']['cross_source_conflict_count'] == 0, 'Raw composition/source-mask differs')
|
||||
|
||||
|
||||
class Evidence:
|
||||
def __init__(self, reader, exp, registration_sha, expected, final):
|
||||
require(final.get('schema') == 'normal-append-ledger-v1-final-audit' and
|
||||
final.get('registration_sha256') == registration_sha and final.get('pass_all') is True and
|
||||
final.get('entry_ids') == final.get('expected_entry_ids') == expected and
|
||||
final.get('expected_order_exact') is True, 'Final ledger authority/complete order differs')
|
||||
require(all(final.get(k) == [] for k in ('extra_files', 'missing_files', 'changed_files',
|
||||
'unsafe_files', 'errors', 'uncommitted_entry_ids')) and final.get('uncommitted_state_unknown') is False,
|
||||
'Incomplete/failed final ledger audit')
|
||||
self.r, self.exp, self.regsha, self.expected = reader, Path(exp), registration_sha, expected
|
||||
self.index, self.tail, self.final = 0, None, final
|
||||
|
||||
def process(self, entry_id, kind):
|
||||
self.index += 1
|
||||
require(self.expected[self.index - 1] == entry_id, 'Analysis process order differs')
|
||||
entry_path = self.exp / f'.append-ledger/entries/{self.index:016d}.json'
|
||||
entry = self.r.json(entry_path)
|
||||
start_path = self.exp / f'.append-ledger/started/{entry_id}.json'
|
||||
start = self.r.json(start_path)
|
||||
job_path = self.exp / f'jobs/{entry_id}.json'
|
||||
process_path = self.exp / 'receipts' / entry_id / 'process.json'
|
||||
require(entry['entry_id'] == start['entry_id'] == entry_id and entry['sequence'] == start['next_sequence'] == self.index and
|
||||
entry['registration_sha256'] == start['registration_sha256'] == self.regsha and
|
||||
entry['prev_entry_sha256'] == start['prev_entry_sha256'] == self.tail and
|
||||
entry['start_sha256'] == self.r.check(start_path)['sha256'] and start['retry_authorized'] is False,
|
||||
'Ledger/start chain differs')
|
||||
incoming = {row['path']: row for row in entry['consumed_inputs']}
|
||||
outgoing = {row['path']: row for row in entry['new_outputs']}
|
||||
require(len(incoming) == len(entry['consumed_inputs']) and len(outgoing) == len(entry['new_outputs']), 'Duplicate ledger files')
|
||||
for path, row in {**incoming, **outgoing}.items():
|
||||
_, bound = self.r.path(path)
|
||||
require(all(row[k] == bound[k] for k in ('bytes', 'sha256')), 'Ledger/checksum authority differs')
|
||||
metadata = entry['metadata']
|
||||
require(metadata['job_file'] == str(job_path) and metadata['process_receipt_file'] == str(process_path) and
|
||||
type(metadata['observed_returncode']) is int and metadata['observed_returncode'] == 0 and
|
||||
str(process_path) in outgoing and str(job_path) in incoming and
|
||||
start['job']['path'] == str(job_path) and start['job']['sha256'] == self.r.check(job_path)['sha256'],
|
||||
'Process/job not owned by committed ledger entry')
|
||||
process, job = self.r.json(process_path), self.r.json(job_path)
|
||||
require(process['entry_id'] == entry_id and process['registration_sha256'] == job['registration_sha256'] == self.regsha and
|
||||
process['job_sha256'] == self.r.check(job_path)['sha256'] and process['complete'] is True and
|
||||
type(process['exit_code']) is int and process['exit_code'] == 0 and process['timed_out'] is False and
|
||||
process['exit_observed_by_parent'] is True and job['kind'] == kind, 'Actual parent exit/job receipt differs')
|
||||
for path, digest in job['input_sha256'].items():
|
||||
require(path in incoming and self.r.check(path)['sha256'] == digest, 'Actual consumed job input differs')
|
||||
for label in ('stdout', 'stderr'):
|
||||
path = self.exp / f'logs/{entry_id}.{label}.log'
|
||||
require(str(path) in outgoing and self.r.check(path)['sha256'] == process[label + '_sha256'], 'Parent log differs')
|
||||
if kind in ('brain', 'update'):
|
||||
require(job['receipt_file'] in outgoing and job['receipt_file'] + '.attempt.json' in outgoing,
|
||||
'Worker/attempt receipt not ledger owned')
|
||||
worker = self.r.json(job['receipt_file'])
|
||||
closure = dict(job['input_sha256'])
|
||||
closure[str(job_path)] = self.r.check(job_path)['sha256']
|
||||
# The AP worker includes its own exact script source in its closure.
|
||||
script = process['argv'][2]
|
||||
closure[script] = self.r.check(script)['sha256']
|
||||
for value in job['sources'].values():
|
||||
require(self.r.check(value['path'])['sha256'] == value['sha256'], 'Worker source differs')
|
||||
closure[value['path']] = value['sha256']
|
||||
require(worker['schema'] == 'phase4ap-isolated-worker-receipt-v1' and worker['complete'] is True and
|
||||
worker['job_id'] == entry_id and worker['kind'] == kind and worker['registration_sha256'] == self.regsha and
|
||||
worker['job_sha256'] == self.r.check(job_path)['sha256'] and worker['verified_input_sha256'] == closure and
|
||||
worker['attempt_sha256'] == self.r.check(job['receipt_file'] + '.attempt.json')['sha256'], 'Worker/attempt binding differs')
|
||||
declared = {str(Path(p).relative_to(job['output_dir'])): row['sha256'] for p, row in outgoing.items()
|
||||
if Path(p).is_relative_to(job['output_dir'])}
|
||||
require(worker['output_files_sha256'] == declared, 'Worker output coverage differs')
|
||||
self.tail = self.r.check(entry_path)['sha256']
|
||||
return dict(job=job, outgoing=outgoing, process_sha256=self.r.check(process_path)['sha256'], process_path=str(process_path))
|
||||
|
||||
def finish(self):
|
||||
require(self.index == len(self.expected) and self.tail == self.final['head_sha256'], 'Missing process or terminal ledger head differs')
|
||||
|
||||
|
||||
def audit_records(reader, exp, reg, regsha, plan, evidence, *, template, inputs, populations):
|
||||
"""Bind all 33,920 tasks and actual update chains; retain only small indexes."""
|
||||
sample = evidence.process('input-generation', 'sample')
|
||||
sampler = reader.json(Path(exp) / 'receipts/input-generation.json')
|
||||
require(sampler['complete'] is True and sampler['registration_sha256'] == regsha and
|
||||
str(Path(exp) / 'receipts/input-generation.json') in sample['outgoing'], 'Sampler receipt not ledger owned')
|
||||
require(sampler['descriptors'] == len(inputs['descriptors']) == 4080 and set(sampler['inputs']) == set(inputs['descriptors']) and
|
||||
sampler['input_inventory_sha256'] == reader.check(Path(exp) / 'protocol/input-inventory.json')['sha256'], 'Actual sampler inventory incomplete')
|
||||
previous, probes, arms, record_hashes = {}, {}, defaultdict(list), []
|
||||
for task in plan['tasks']:
|
||||
key = task_key(task); result_path = Path(exp) / f'results/{key}.json'
|
||||
record = reader.json(result_path)
|
||||
require(record['schema'] == 'normal-task-result-v1' and record['complete'] is True and
|
||||
record['registration_sha256'] == regsha and canonical(record['task']) == canonical(task), 'Actual result/task differs')
|
||||
branch = task['block_id'], task['arm']
|
||||
overlay = previous.get(branch, reg['initial_overlay'])
|
||||
require(record['overlay_before'] == overlay, 'Delta ancestry changed or probe fed back')
|
||||
brain = evidence.process(key + '--brain', 'brain')
|
||||
audit_case(reader, exp, task, brain['job'], template=template, inputs=inputs, sampler=sampler,
|
||||
populations=populations, population_file=reg['population_file'], output_cap=reg['budget']['output_cap_bytes'])
|
||||
job = brain['job']; output = Path(exp) / 'runs' / key
|
||||
require(record['brain_process_receipt_path'] == brain['process_path'] and
|
||||
record['checkpoint_dir'] == job['output_dir'] == str(output) and
|
||||
all(job[k] == overlay[k] for k in ('overlay_file', 'overlay_manifest')) and
|
||||
job['diagnostic_mode'] == 'light', 'Brain result/overlay path differs')
|
||||
manifest = reader.json(output / 'checkpoint-manifest.json')
|
||||
require(record['checkpoint_manifest_sha256'] == record['brain_audit']['checkpoint_manifest_sha256'] ==
|
||||
reader.check(output / 'checkpoint-manifest.json')['sha256'] and
|
||||
record['brain_audit']['task_id'] == task['task_id'], 'Checkpoint binding differs')
|
||||
for name, digest in manifest['files_sha256'].items():
|
||||
require(reader.check(output / name)['sha256'] == digest, 'Checkpoint payload differs')
|
||||
record_hashes.append([task['task_id'], reader.check(result_path)['sha256']])
|
||||
if task['kind'] == 'probe':
|
||||
require(str(result_path) in brain['outgoing'], 'Probe result not ledger owned')
|
||||
probes[(task['block_id'], task['arm'], task['checkpoint'], task['recipe']['cue'])] = record
|
||||
continue
|
||||
update = evidence.process(key + '--update', 'update')
|
||||
cpu = evidence.process(key + '--verify', 'cpu_verify')
|
||||
require(record['update_process_receipt_path'] == update['process_path'] and record['cpu_process_receipt_path'] == cpu['process_path'] and
|
||||
str(result_path) in cpu['outgoing'], 'Training result/parent process ownership differs')
|
||||
authority = reader.json(record['epoch_authority']['path'])
|
||||
require(reader.check(record['epoch_authority']['path'])['sha256'] == record['epoch_authority']['sha256'] ==
|
||||
update['job']['authority_sha256'] == cpu['job']['authority_sha256'] and authority['epoch_id'] == task['task_id'] and
|
||||
authority['checkpoint_dir'] == str(output) and authority['checkpoint_manifest_sha256'] == record['checkpoint_manifest_sha256'],
|
||||
'Original E authority differs')
|
||||
command = dict(steps=1200, compartment=task['compartment_verbatim'], us_tick=task['recipe']['us']['tick'],
|
||||
d_command=task['recipe']['D_command'], frozen=not task['recipe']['update_enabled'], trace_backend='torch')
|
||||
require(authority['command'] == command, 'Original E command changed')
|
||||
valid = reader.json(record['cpu_validation']['path'])
|
||||
after = dict(overlay_file=str(Path(exp) / 'updates' / key / 'delta-after.npz'),
|
||||
overlay_manifest=str(Path(exp) / 'updates' / key / 'overlay-manifest.json'))
|
||||
require(record['update_dir'] == update['job']['output_dir'] == cpu['job']['update_dir'] == str(Path(exp) / 'updates' / key) and
|
||||
record['cpu_validation']['path'] == cpu['job']['receipt_file'] and record['cpu_validation']['path'] in cpu['outgoing'] and
|
||||
record['epoch_authority']['path'] == update['job']['authority_file'] == cpu['job']['authority_file'] and
|
||||
authority['files']['state'] == dict(path=str(output / 'state.npz'), sha256=reader.check(output / 'state.npz')['sha256']) and
|
||||
authority['files']['overlay_before'] == dict(path=overlay['overlay_file'], sha256=reader.check(overlay['overlay_file'])['sha256']) and
|
||||
authority['files']['overlay_manifest_before'] == dict(path=overlay['overlay_manifest'], sha256=reader.check(overlay['overlay_manifest'])['sha256']) and
|
||||
record['after_overlay'] == after and reader.check(record['cpu_validation']['path'])['sha256'] == record['cpu_validation']['sha256'] and
|
||||
valid['complete'] is True and valid['frozen_U_verify_receipt_recomputed'] is True and valid['actual_sealed_events_used'] is True and
|
||||
valid['epoch_authority_sha256'] == record['epoch_authority']['sha256'] and
|
||||
valid['after_overlay_sha256'] == reader.check(after['overlay_file'])['sha256'], 'Independent CPU update validation differs')
|
||||
if task['arm'] in ('d_zero', 'frozen', 'cs_only'):
|
||||
require(not reader.arrays(after['overlay_file'])['plastic_delta_mv'].view(np.uint32).any(), 'Zero control contains nonzero delta')
|
||||
previous[branch] = after
|
||||
arms[branch].append(dict(result=record_hashes[-1], brain=brain['process_sha256'],
|
||||
update=update['process_sha256'], cpu=cpu['process_sha256'], requested=task['recipe']['us']['requested']))
|
||||
evidence.finish()
|
||||
require(len(probes) == 3920 and len(arms) == 280 and len(record_hashes) == 33920, 'Incomplete actual task inventory')
|
||||
return probes, arms, sha(record_hashes)
|
||||
|
||||
|
||||
def build_registry(trial, plan, *, nodes, populations, population_binding_sha, regsha, input_hashes):
|
||||
membership = M.validate_populations(nodes, populations)
|
||||
blocks = {}
|
||||
inputs = {(r['block_id'], r['cue']): r for r in plan['evaluation_inputs']}
|
||||
for block in trial['plan']['blocks']:
|
||||
identity = block['block_id']
|
||||
source_rows = [r for r in trial['seed_manifest']['independent_streams']
|
||||
if r['key'][0] == identity and r['key'][1] == 'normal' and r['split'] in ('training', 'design')]
|
||||
sources = [dict(stream_id=P._FROZEN['trial_plan']._stream_id(P.MASTER, r['split'], r['key']),
|
||||
seed=r['seed'], split=r['split']) for r in source_rows]
|
||||
blocks[identity] = dict(mode=block['mode'], dan_type=block['dan_type'], compartment_verbatim=block['compartment_verbatim'],
|
||||
conditioned_cue=ODORS[block['initial_reinforced_cue']], replicate=block['replicate'], training_sources=sources,
|
||||
evaluation_sources={ODORS[c]: {k: inputs[(identity, c)][k] for k in ('stream_id', 'seed', 'split')} for c in ODORS},
|
||||
evaluation_input_sha256={ODORS[c]: input_hashes[(identity, c)] for c in ODORS})
|
||||
registry = dict(schema=G.REGISTRY_SCHEMA, protocol_sha256=regsha, population_binding_sha256=population_binding_sha,
|
||||
nodes_raw_sha256=M._hash(nodes), population_membership_sha256=membership['membership_sha256'], blocks=blocks)
|
||||
G.validate_registry(registry, expected_sha256=G.descriptor_sha256(registry))
|
||||
return registry
|
||||
|
||||
|
||||
def compact_metric(metric):
|
||||
return dict(rawS=metric['rawS'], rawB=metric['rawB'], separation=metric['separation'],
|
||||
cues={cue: dict(state_pre=summary['pre_state_raw_sha256'], state_post=summary['post_state_raw_sha256'],
|
||||
populations={name: {k: v for k, v in group.items() if not isinstance(v, list)}
|
||||
for name, group in summary['populations'].items()}) for cue, summary in metric['cues'].items()})
|
||||
|
||||
|
||||
def scientific_reports(probes, arms, *, registry, authority, nodes, populations, load_state):
|
||||
"""One cell's terminal vectors at a time; curve outputs contain no raw vectors."""
|
||||
curves, compact_reports = [], []
|
||||
|
||||
def cells():
|
||||
for mode in M.MODES:
|
||||
for dan in M.DAN_TYPES:
|
||||
for conditioned in M.CUES:
|
||||
rows = []
|
||||
selected = [(key, b) for key, b in registry['blocks'].items()
|
||||
if (b['mode'], b['dan_type'], b['conditioned_cue']) == (mode, dan, conditioned)]
|
||||
for identity, block in selected:
|
||||
arm_values = {}
|
||||
for name, legacy_name in ARM_NAMES.items():
|
||||
pre = {ODORS[c]: load_state(probes[(identity, name, 0, c)]) for c in ODORS}
|
||||
terminal = None
|
||||
for point in POINTS:
|
||||
post = pre if point == 0 else {ODORS[c]: load_state(probes[(identity, name, point, c)]) for c in ODORS}
|
||||
metric = M.arm_metrics(pre, post, conditioned_cue=conditioned, nodes=nodes, populations=populations)
|
||||
curves.append(dict(block_id=identity, arm=name, checkpoint=point, metrics=compact_metric(metric)))
|
||||
if point == 50:
|
||||
terminal = metric
|
||||
history = arms[(identity, name)]
|
||||
require(len(history) == (150 if name == 'unpaired' else 100), 'Missing actual training/control epochs')
|
||||
execution = dict(complete=True, recording_verified=True, receipt_sha256=sha(history), assay='normal',
|
||||
epoch_duration_ms=120., cs_duration_ms=100., us_tick=900, completed_epochs=len(history),
|
||||
reinforcement_opportunities=sum(r['requested'] for r in history), terminal_pairings=50)
|
||||
arm_values[legacy_name] = dict(metrics=terminal, execution=execution)
|
||||
rows.append(dict(replicate_id=identity, replicate_unit='independent_training',
|
||||
training_stream_ids=[x['stream_id'] for x in block['training_sources']],
|
||||
evaluation_stream_ids=[block['evaluation_sources'][c]['stream_id'] for c in M.CUES],
|
||||
assay='normal', mode=mode, dan_type=dan, conditioned_cue=conditioned, arms=arm_values))
|
||||
report = G.evaluate_acquisition(rows, assay='normal', mode=mode, dan_type=dan,
|
||||
conditioned_cue=conditioned, registry=registry, authority=authority)
|
||||
compact_reports.append({k: v for k, v in report.items()
|
||||
if k not in ('acquisition_metric_inputs', 'frozen_acquisition_result')})
|
||||
yield report
|
||||
|
||||
cohort = G.summarize_cohort(cells(), registry=registry, authority=authority, required_assays=('normal',))
|
||||
require(cohort['complete_inventory'], 'Missing normal cells')
|
||||
return dict(cells=compact_reports, cohort=cohort, curves=curves)
|
||||
|
||||
|
||||
def legacy_audit(reports, declared_mapping):
|
||||
"""G.H_MAPPING source layout; call the unchanged M scalar twice per group."""
|
||||
require(declared_mapping == G.H_MAPPING, 'Explicit original registered H mapping required')
|
||||
lookup = {(r['mode'], r['dan_type'], r['conditioned_cue']): r for r in reports}
|
||||
require(len(reports) == len(lookup) == 8, 'Exact eight-cell legacy input required')
|
||||
groups = []
|
||||
for mode in M.MODES:
|
||||
for cue in M.CUES:
|
||||
selected = {d: lookup[(mode, d, cue)] for d in M.DAN_TYPES}
|
||||
outcomes = {}
|
||||
for source in M.DAN_TYPES:
|
||||
gains = {label: [r['population_separation_gains']['MBON'] for r in selected[dan]['replicates']]
|
||||
for dan, label in (('PAM15', 'appetitive-conditioning'), ('PPL103', 'aversive-conditioning'))}
|
||||
for name, label in (('D=0', 'd-zero-control'), ('random reward', 'random-reward-control'), ('frozen', 'frozen-brain-control')):
|
||||
controls = selected[source]['legacy_control_MBON_gains'][name]
|
||||
require(set(controls) == {r['replicate_id'] for r in selected[source]['replicates']}, 'Legacy replicate control source differs')
|
||||
gains[label] = [controls[r['replicate_id']] for r in selected[source]['replicates']]
|
||||
outcomes[source] = M.legacy_h_mean_control_audit(gains)
|
||||
groups.append(dict(mode=mode, conditioned_cue=cue, control_sources=outcomes,
|
||||
both_pass=all(v['predicate_pass'] for v in outcomes.values())))
|
||||
return dict(schema=G.SCHEMA, status='CONDITIONAL-AUDIT', declared_mapping=declared_mapping, groups=groups,
|
||||
both_pass=all(g['both_pass'] for g in groups), original_H_data_layout_reproduced=False,
|
||||
new_stricter_control_source_mapping=True, **G._scope())
|
||||
|
||||
|
||||
def analyze(exp, registration_sha256, *, verified_inventory, final_ledger):
|
||||
exp, reader = Path(exp), Reader(verified_inventory)
|
||||
regpath = exp / 'protocol/preregistered.json'
|
||||
require(reader.check(regpath)['sha256'] == registration_sha256, 'Registration authority differs')
|
||||
reg = reader.json(regpath)
|
||||
require(reg['schema'] == 'normal-conditioning-registration-v1' and reg['scientific_scope'] == 'normal-acquisition-only' and
|
||||
reg['subsequent_assays_authorized'] is False, 'Wrong scientific authority')
|
||||
for collection in ('source_sha256', 'input_sha256', 'prepared_sha256'):
|
||||
for path, digest in reg[collection].items():
|
||||
require(reader.check(path)['sha256'] == digest, 'Registered dependency differs')
|
||||
plan = reader.json(exp / 'protocol/normal-plan.json')
|
||||
full = reader.json(reg['original_full_trial_plan']['path'])
|
||||
require(reader.check(reg['original_full_trial_plan']['path'])['sha256'] == reg['original_full_trial_plan']['sha256'] == P.AO_TRIAL_FILE_SHA256,
|
||||
'Original AO full plan differs')
|
||||
evaluation = P.expand_pinned_evaluation(full)
|
||||
P.validate_normal_plan(plan, full, evaluation)
|
||||
gates = reader.json(exp / 'protocol/gates.json')
|
||||
require(gates['H_mapping'] == G.H_MAPPING and gates['all_eight_cells_required'] is True and
|
||||
gates['same_replicate_conjunction_at_least'] == 3 and gates['training_replicates'] == 5 and gates['terminal_checkpoint'] == 50 and
|
||||
gates['intermediate_checkpoints_cannot_rescue_terminal'] is True, 'Registered scientific policy differs')
|
||||
template = reader.json(exp / 'protocol/case-template.json')
|
||||
nodes_path = Path(template['graph_dir']) / 'nodes.npy'
|
||||
nodes = np.load(io.BytesIO(reader.raw(nodes_path)), allow_pickle=False)
|
||||
require(nodes.dtype == np.int32 and len(nodes) == 166700, 'Full original graph nodes required')
|
||||
require('readout_population_file' in reg, 'Registered full legacy/non-MBON readout populations missing')
|
||||
populations = reader.arrays(reg['readout_population_file'])
|
||||
original = reader.arrays(reg['population_file'])
|
||||
for name in ('MBON', 'MBON01', 'MBON12'):
|
||||
require(np.array_equal(original[name], populations[name]), 'Original anatomical population changed')
|
||||
M.validate_populations(nodes, populations)
|
||||
require('readout_population_binding_file' in reg, 'Registered anatomical binding file missing')
|
||||
population_binding_sha = reader.check(reg['readout_population_binding_file'])['sha256']
|
||||
evidence = Evidence(reader, exp, registration_sha256, expected_entries(plan), final_ledger)
|
||||
inputs = reader.json(exp / 'protocol/input-inventory.json')
|
||||
probes, arms, inventory_sha = audit_records(reader, exp, reg, registration_sha256, plan, evidence,
|
||||
template=template, inputs=inputs, populations=original)
|
||||
input_hashes, seen_receipts = {}, set()
|
||||
|
||||
def load_state(record):
|
||||
task = record['task']; key = task_key(task)
|
||||
receipt = record['brain_process_receipt_path']
|
||||
require(receipt not in seen_receipts, 'Probe execution reused across snapshots')
|
||||
seen_receipts.add(receipt)
|
||||
csid = inputs['task_inputs'][task['task_id']]
|
||||
recipe = task['recipe']
|
||||
expected_descriptor = dict(mode=task['mode'], cue=recipe['cue'], seed=recipe['input']['seed'], steps=1200,
|
||||
cs_start_tick=0, cs_stop_tick_exclusive=1000, source_stream_id=recipe['input']['stream_id'],
|
||||
table_id=task['mode'] + '--' + recipe['cue'])
|
||||
require(csid == sha(expected_descriptor) and inputs['descriptors'][csid] == expected_descriptor,
|
||||
'Evaluation seed/stream/clock mapping differs from original plan')
|
||||
source = exp / f'inputs/generated/{csid}.npz'
|
||||
generated = reader.json(exp / f'inputs/generated/{csid}.json')
|
||||
require(generated['descriptor'] == inputs['descriptors'][csid] and generated['requests_sha256'] == reader.check(source)['sha256'],
|
||||
'Actual evaluation input descriptor differs')
|
||||
case = exp / 'cases' / key
|
||||
binding = reader.json(case / 'input-binding.json')
|
||||
require(binding['CS_source'] == dict(path=str(source), sha256=reader.check(source)['sha256']) and
|
||||
binding['CS_descriptor_id'] == csid and binding['task_id'] == task['task_id'], 'Probe shared input binding differs')
|
||||
requests, cs, us = (reader.arrays(path) for path in (case / 'requests.npz', source, case / 'us_requests.npz'))
|
||||
require(set(requests) == set(cs) == set(us) == {'tick', 'neuron_idx'} and
|
||||
all(not len(v) for v in us.values()) and all(np.array_equal(requests[k], cs[k]) for k in requests), 'Probe includes US or changed CS')
|
||||
state = reader.arrays(Path(record['checkpoint_dir']) / 'state.npz')
|
||||
actual = M.validate_state(state, nodes=nodes, steps=1200)
|
||||
require(actual['hashes'] == record['brain_audit']['state_raw_sha256'], 'Actual probe raw arrays differ')
|
||||
return state
|
||||
|
||||
for item in plan['evaluation_inputs']:
|
||||
record = probes[(item['block_id'], 'paired', 0, item['cue'])]
|
||||
csid = inputs['task_inputs'][record['task']['task_id']]
|
||||
input_hashes[(item['block_id'], item['cue'])] = reader.check(exp / f'inputs/generated/{csid}.npz')['sha256']
|
||||
registry = build_registry(full, plan, nodes=nodes, populations=populations, population_binding_sha=population_binding_sha,
|
||||
regsha=registration_sha256, input_hashes=input_hashes)
|
||||
authority = dict(schema=G.AUTHORITY_SCHEMA, registry_sha256=G.descriptor_sha256(registry),
|
||||
verification_receipt_sha256=sha(final_ledger), execution_inventory_sha256=inventory_sha,
|
||||
population_binding_sha256=population_binding_sha)
|
||||
result = scientific_reports(probes, arms, registry=registry, authority=authority, nodes=nodes, populations=populations, load_state=load_state)
|
||||
require(len(seen_receipts) == 3920, 'Not every independently executed probe was analyzed')
|
||||
result['legacy_H'] = legacy_audit(result['cells'], gates['H_mapping'])
|
||||
return dict(schema='normal-scientific-analysis-v1', status='CONDITIONAL-PENDING-OUTER-INTEGRITY',
|
||||
registration_sha256=registration_sha256, normal_plan_sha256=plan['payload_sha256'], registry=registry, authority=authority,
|
||||
analysis=result, analyzed_probe_calls=3920, curve_points=1960, consumed_file_count=len(reader.seen),
|
||||
subsequent_assays_status='NOT-RUN', subsequent_assays_authorized=False, candidate_generated=False,
|
||||
learning_pass_claimed=False, scientific_learning_pass_claimed=False, data_backed_claimed=False,
|
||||
external_full_tree_anatomy_historical_integrity_verified_here=False,
|
||||
retained_raw_evidence='original state and receipt files; terminal raw metric vectors recomputable, not duplicated in report')
|
||||
@@ -0,0 +1,199 @@
|
||||
"""Pure normal-only adapter of the AO-pinned, master-20260930 inventory.
|
||||
|
||||
No sampling, brain execution, file writes, biological identity certification,
|
||||
or execution authorization. Import reads and SHA-checks six frozen sources.
|
||||
The trial argument must reproduce the ORIGINAL AO saved-file bytes under its
|
||||
documented JSON encoding. The evaluation argument is a new exact expansion of
|
||||
the old pinned policy, NOT an independently archived AO evaluation artifact.
|
||||
Physical inputs, actual DAN mapping, checkpoints, model and process receipts
|
||||
remain the registering executor's responsibility. No scientific gate changes.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import builtins
|
||||
from collections import Counter
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
import types
|
||||
|
||||
|
||||
SCHEMA = "normal-conditioning-plan-v1"
|
||||
MASTER = 20260930
|
||||
AO_TRIAL_FILE_SHA256 = "a7bda850ee87df4d9f647994e1a1a4074dfea5793184edb1822ab3d8c02e8216"
|
||||
AO_REGISTRATION_SHA256 = "9e2ed05879ce279da7dc0b4cac09a44d67665c230b56db94e2ca39c645bdc250"
|
||||
AP_REGISTRATION_SHA256 = "02a03b536a9f14196ad4b92fa9565b592732c6c863e72eeaee89b3b0ea8ed37d"
|
||||
AO_TRIAL_PATH = "/data/digital-drosophila/experiments/phase4ao-conditioning-interface/protocol/full-trial-plan.json"
|
||||
FROZEN_DIRECTORY = Path(__file__).resolve().parent.parent / "olfactory-conditioning-lab-v1"
|
||||
SOURCE_PINS = {
|
||||
"seed_registry.py": "0da033b132095ec3087b5d9f64e53c2e391fa50ab0b7653b31296eeb84799b7e",
|
||||
"trial_plan.py": "6fed3f494d075339a7e5b001d43b2598640b189e038952fbd4d41200bacac587",
|
||||
"evaluation_plan.py": "991c813ff3322b230947f302b12b04ec382c3b632817f94b698101e4b17efa7d",
|
||||
"evaluation_policy.py": "21331a9ff3567dc6f6399e16bb91ef486d74231f5db51799beb6dd1bf71d022b",
|
||||
"PROTOCOL_DRAFT.md": "8ebecb1f3d012ddc29a1cb727269dd277629c53565e09978bf9dbf7140cb8508",
|
||||
"EVALUATION_POLICY_DRAFT.md": "a84170a61564715a1532f20df4c6a330f0f9725c383db48b8f3e1a4b5fba0bc8",
|
||||
}
|
||||
|
||||
|
||||
def _require(condition, message):
|
||||
if not condition:
|
||||
raise ValueError(message)
|
||||
|
||||
|
||||
def _canonical(value):
|
||||
return json.dumps(value, sort_keys=True, separators=(",", ":"),
|
||||
ensure_ascii=False, allow_nan=False)
|
||||
|
||||
|
||||
def _sha(value):
|
||||
return hashlib.sha256(_canonical(value).encode("utf-8")).hexdigest()
|
||||
|
||||
|
||||
def _load_frozen():
|
||||
"""Private module graph; never change sys.path or ordinary module caches."""
|
||||
sources = {}
|
||||
for filename, expected in SOURCE_PINS.items():
|
||||
raw = (FROZEN_DIRECTORY / filename).read_bytes()
|
||||
_require(hashlib.sha256(raw).hexdigest() == expected,
|
||||
"Frozen source pin mismatch: " + filename)
|
||||
sources[filename] = raw
|
||||
modules = {}
|
||||
ordinary_import = builtins.__import__
|
||||
|
||||
def private_import(name, globals=None, locals=None, fromlist=(), level=0):
|
||||
if level == 0 and name in modules:
|
||||
return modules[name]
|
||||
return ordinary_import(name, globals, locals, fromlist, level)
|
||||
|
||||
for name in ("seed_registry", "trial_plan", "evaluation_plan", "evaluation_policy"):
|
||||
module = types.ModuleType("_normal_frozen_" + name)
|
||||
module.__file__ = str(FROZEN_DIRECTORY / (name + ".py"))
|
||||
module.__dict__["__builtins__"] = dict(vars(builtins), __import__=private_import)
|
||||
exec(compile(sources[name + ".py"], module.__file__, "exec"), module.__dict__)
|
||||
modules[name] = module
|
||||
return modules
|
||||
|
||||
|
||||
_FROZEN = _load_frozen()
|
||||
|
||||
|
||||
def _validate_original_trial(trial):
|
||||
_require(type(trial) is dict and set(trial) ==
|
||||
{"plan", "seed_manifest", "budget", "payload_sha256"}, "Full original trial payload required")
|
||||
_require(type(trial["plan"]["master"]) is int and trial["plan"]["master"] == MASTER,
|
||||
"Original AO master is fixed; no seed selection")
|
||||
# This is the exact LF serialization used by AO engineering_prepare.save.
|
||||
# Its registered file pin is stronger than reconstructing with a new seed.
|
||||
encoded = json.dumps(trial, sort_keys=True, indent=2, ensure_ascii=False,
|
||||
allow_nan=False) + "\n"
|
||||
_require(hashlib.sha256(encoded.encode("utf-8")).hexdigest() == AO_TRIAL_FILE_SHA256,
|
||||
"Trial does not reproduce the AO registered full-trial-plan file")
|
||||
_require(_sha({k: v for k, v in trial.items() if k != "payload_sha256"}) ==
|
||||
trial["payload_sha256"], "Original trial self-hash mismatch")
|
||||
|
||||
|
||||
def _expand_validated_trial(trial):
|
||||
# Private frozen assembly is safe AFTER the exact archived-file pin above;
|
||||
# avoid the old public APIs' redundant 68,000-epoch trial reconstruction.
|
||||
policy = _FROZEN["evaluation_policy"]._assemble(trial)
|
||||
return _FROZEN["evaluation_plan"]._assemble(trial, policy["config"])
|
||||
|
||||
|
||||
def expand_pinned_evaluation(full_trial_payload):
|
||||
"""Expand the fixed historical policy; no new choices or sampled inputs."""
|
||||
_validate_original_trial(full_trial_payload)
|
||||
return _expand_validated_trial(full_trial_payload)
|
||||
|
||||
|
||||
def build_normal_plan(full_trial_payload, full_evaluation_payload):
|
||||
"""Return 33,920 ordered tasks; caller supplies both complete authorities."""
|
||||
trial, evaluation = full_trial_payload, full_evaluation_payload
|
||||
_validate_original_trial(trial)
|
||||
expected_evaluation = _expand_validated_trial(trial)
|
||||
_require(_canonical(evaluation) == _canonical(expected_evaluation),
|
||||
"Evaluation must exactly expand the AO-pinned evaluation policy")
|
||||
snapshots = {(s["block_id"], s["arm"], s["completed_epochs"]): s
|
||||
for s in evaluation["snapshots"] if s["assay"] == "normal"}
|
||||
probes = {(p["snapshot_id"], p["cue"]): p
|
||||
for p in evaluation["probes"] if p["assay"] == "normal"}
|
||||
tasks, inputs, blocks = [], [], []
|
||||
for block in trial["plan"]["blocks"]:
|
||||
common = dict(block_id=block["block_id"], mode=block["mode"], dan_type=block["dan_type"],
|
||||
compartment_verbatim=block["compartment_verbatim"],
|
||||
reinforced_cue=block["initial_reinforced_cue"], replicate=block["replicate"],
|
||||
assay="normal", steps=1200, artifact_validation_required=True)
|
||||
blocks.append(dict(common, DAN_target_binding=block["DAN_target_binding"]))
|
||||
for cue in ("A", "B"):
|
||||
sid = block["block_id"] + "/normal/paired/checkpoint-00"
|
||||
inputs.append(dict(block_id=block["block_id"], cue=cue, **probes[(sid, cue)]["input"]))
|
||||
suite = next(s for s in block["suites"] if s["assay"] == "normal")
|
||||
for arm in suite["arms"]:
|
||||
name = arm["arm"]
|
||||
delta = dict(arm["delta_start"])
|
||||
|
||||
def append_probes(completed):
|
||||
snapshot = snapshots.get((block["block_id"], name, completed))
|
||||
if snapshot is None:
|
||||
return
|
||||
_require(snapshot["delta_source"] == delta, "Snapshot delta dependency differs")
|
||||
for cue in ("A", "B"):
|
||||
recipe = probes[(snapshot["snapshot_id"], cue)]
|
||||
tasks.append(dict(common, kind="probe", arm=name, task_id=recipe["probe_id"],
|
||||
probe_id=recipe["probe_id"], snapshot_id=snapshot["snapshot_id"],
|
||||
checkpoint=snapshot["checkpoint"], completed_epochs=completed,
|
||||
evaluation_input_id=recipe["input"]["input_id"], delta_dependency=dict(delta),
|
||||
delta_output_id=None, neural_state_policy="common_frozen_reset_independent_probe",
|
||||
carry_between_epochs=[], original_E_required=False, cpu_validation_required=False,
|
||||
feedback_to_training_or_idle=False, recipe=recipe, snapshot_binding=snapshot,
|
||||
source_binding=dict(payload_sha256=evaluation["payload_sha256"],
|
||||
record_id=recipe["probe_id"], record_sha256=_sha(recipe))))
|
||||
|
||||
append_probes(0)
|
||||
for completed, epoch in enumerate(arm["epochs"], 1):
|
||||
tasks.append(dict(common, kind="train", arm=name, task_id=epoch["epoch_id"],
|
||||
epoch_id=epoch["epoch_id"], epoch_index=epoch["epoch_index"],
|
||||
delta_dependency=dict(delta), delta_output_id=epoch["epoch_id"] + "/delta-after",
|
||||
neural_state_policy=epoch["initial_neural_state"],
|
||||
carry_between_epochs=list(arm["carry_between_epochs"]),
|
||||
original_E_required=True, cpu_validation_required=True,
|
||||
feedback_to_training_or_idle=True, recipe=epoch,
|
||||
source_binding=dict(payload_sha256=trial["payload_sha256"],
|
||||
record_id=epoch["epoch_id"], record_sha256=_sha(epoch))))
|
||||
delta = dict(kind="epoch_delta_after", source=epoch["epoch_id"] + "/delta-after")
|
||||
append_probes(completed)
|
||||
counts = Counter(row["kind"] for row in tasks)
|
||||
_require(counts == {"train": 30000, "probe": 3920} and len(inputs) == 80 and len(blocks) == 40,
|
||||
"Normal inventory changed")
|
||||
_require(len({t["task_id"] for t in tasks}) == len(tasks), "Task IDs must be unique")
|
||||
result = dict(schema=SCHEMA, master=MASTER, assay="normal", blocks=blocks,
|
||||
tasks=tasks, evaluation_inputs=inputs,
|
||||
inventory=dict(blocks=40, training_replicates_per_cell=5, arms_per_block=7,
|
||||
nominal_reinforcements=50, checkpoints=[0, 1, 2, 5, 10, 20, 50],
|
||||
train_calls=30000, probe_calls=3920, brain_calls=33920,
|
||||
original_E_calls=30000, training_cpu_validation_calls=30000,
|
||||
brain_steps=40704000, biological_seconds=4070.4, evaluation_inputs=80,
|
||||
baseline_execution="execute_each_snapshot", baseline_output_deduplication=False),
|
||||
provenance=dict(trial_payload_sha256=trial["payload_sha256"],
|
||||
seed_manifest_sha256=trial["seed_manifest"]["payload_sha256"],
|
||||
evaluation_payload_sha256=evaluation["payload_sha256"],
|
||||
evaluation_config_sha256=evaluation["config_sha256"],
|
||||
ao_trial_file_sha256=AO_TRIAL_FILE_SHA256, ao_trial_path=AO_TRIAL_PATH,
|
||||
ao_registration_sha256=AO_REGISTRATION_SHA256, ap_registration_sha256=AP_REGISTRATION_SHA256,
|
||||
frozen_source_sha256=SOURCE_PINS,
|
||||
evaluation_authority="exact expansion of AO-pinned policy; not a historical saved evaluation artifact",
|
||||
external_inputs_mapping_processes_and_physical_source_files_verified=False),
|
||||
execution_authorized=False, inputs_generated=False, new_seed_streams=0,
|
||||
learning_pass_claimed=False, subsequent_assays_included=False)
|
||||
result["payload_sha256"] = _sha(result)
|
||||
# No returned nested structure aliases either caller argument or module pins.
|
||||
return json.loads(_canonical(result))
|
||||
|
||||
|
||||
def validate_normal_plan(payload, full_trial_payload, full_evaluation_payload):
|
||||
"""Fail closed even if a modified plan has been given a fresh self-hash."""
|
||||
_require(type(payload) is dict and "payload_sha256" in payload, "Normal payload required")
|
||||
_require(_sha({k: v for k, v in payload.items() if k != "payload_sha256"}) ==
|
||||
payload["payload_sha256"], "Normal plan self-hash mismatch")
|
||||
expected = build_normal_plan(full_trial_payload, full_evaluation_payload)
|
||||
_require(_canonical(payload) == _canonical(expected), "Normal plan exact reconstruction mismatch")
|
||||
return True
|
||||
@@ -0,0 +1,205 @@
|
||||
"""Register only normal acquisition; never sample inputs or execute a brain.
|
||||
|
||||
Prior sealed files stay read-only. Complete historical integrity is checked at
|
||||
the phase boundary; each trial rehashes its actual runtime dependency closure,
|
||||
not every historical engineering result. No source or budget changes after
|
||||
registration. Outcome files have no invented pre-outcome hashes.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import argparse
|
||||
import copy
|
||||
from datetime import datetime, timezone, timedelta
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
from normal_io import *
|
||||
import normal_plan as PLAN
|
||||
|
||||
AQ_EXP = ROOT/'experiments/phase4aq-conditioning-execution'
|
||||
AP_EXP = ROOT/'experiments/phase4ap-conditioning-interface-v2'
|
||||
AO_EXP = ROOT/'experiments/phase4ao-conditioning-interface'
|
||||
AQ_ANCHORS = {
|
||||
'protocol/preregistered.json':'dad0ba33ded8c6725662c419525ef4185a6ff169042a402c18d0bd760dad7358',
|
||||
'manifest.json':'2dc0feca75f718f2ee0d7c9240da503221823573fd25f1344d2fd97d97eb2db7',
|
||||
'audit/final-status.json':'dcbb58f296bd0d51e3c8757f0c45dd5585b3a76f8c2a0b5881f4c14076721882',
|
||||
}
|
||||
H_ANCHORS = {
|
||||
'audit/phase4h.py':'28bb2ab7c4c95af3d95b0bf0bc45a5a9bea791996c59ce296ec66b71e01b1695',
|
||||
'mappings/mbon-to-downstream-actual-edges.parquet':'76bac27c50cec41c48fd6414bcef5a6e270753ac4062b92537f38226018e9278',
|
||||
'manifests/checksums.sha256':'1ea0394fd0477bb40d656ed0854108964f3809d633b5561bed9de43cda630ba1',
|
||||
'manifests/manifest.json':'d1f187f164f7775a1a02fff259c8f5e31ae035929d808c3876cfc0013d19c73c',
|
||||
}
|
||||
|
||||
# Exact arrays consumed by the pinned isolated worker, not every reference file
|
||||
# colocated in its graph/APL directories. Tests compare these to that worker.
|
||||
GRAPH_FILES = ('nodes.npy', 'edge_id.npy', 'src.npy', 'dst.npy', 'signed_raw.npy', 'ptr.npy', 'weights.npy')
|
||||
APL_FILES = ('input_matrix.npy', 'output_matrix.npy', 'kc_globals.npy', 'apl_globals.npy')
|
||||
|
||||
def runtime_array_paths(template):
|
||||
return {str(Path(template['graph_dir'])/name) for name in GRAPH_FILES} | {
|
||||
str(Path(template['apl_bundle_dir'])/name) for name in APL_FILES} | {template['coefficients_path']}
|
||||
|
||||
def readout_populations(population_file):
|
||||
import numpy as np
|
||||
import pyarrow.parquet as pq
|
||||
h=ROOT/'experiments/phase4h-dopamine-plasticity'
|
||||
verify({str(h/p):s for p,s in H_ANCHORS.items()})
|
||||
rows=pq.read_table(h/'mappings/mbon-to-downstream-actual-edges.parquet',columns=['target_neuron_idx'])['target_neuron_idx'].to_numpy()
|
||||
require(rows.dtype==np.int32 and len(rows)==39279 and np.all((rows>=0)&(rows<166700)), 'Original H endpoint schema differs')
|
||||
old=npz(population_file)
|
||||
result={k:old[k] for k in ('MBON','MBON01','MBON12')}
|
||||
result['legacyDownstream']=np.unique(rows).astype(np.int32)
|
||||
result['nonMBONDownstream']=np.setdiff1d(result['legacyDownstream'],result['MBON'])
|
||||
require(not len(np.setdiff1d(result['MBON'],result['legacyDownstream'])),'H downstream no longer includes all MBON')
|
||||
hashes={k:hashlib.sha256(v.tobytes()).hexdigest() for k,v in result.items()}
|
||||
require(hashes['legacyDownstream']=='ce9edbb56854be8f6891bfb83559dd7529c70acac6867864947f32f933175dbc' and
|
||||
hashes['nonMBONDownstream']=='01e3fbdde8bf2558665f142cdf546d8b89b4898427b90e2f4368f21f4e241a7f',
|
||||
'Actual H readout membership changed')
|
||||
return result,dict(source_sha256={str(h/p):s for p,s in H_ANCHORS.items()},
|
||||
original_populations=pin(population_file),definition='unique actual H MBON-edge target_neuron_idx, int32; no plastic/active subset',
|
||||
nonMBON_definition='exact set difference legacyDownstream minus full anatomical MBON',
|
||||
counts={k:len(v) for k,v in result.items()},raw_membership_sha256=hashes,
|
||||
historical_current_model_source_used=False,original_sealed_audit_source_used=True)
|
||||
|
||||
def historical_integrity():
|
||||
verify({str(AQ_EXP/p):s for p,s in AQ_ANCHORS.items()})
|
||||
ar = read(AQ_EXP/'protocol/preregistered.json')
|
||||
verify(ar['source_sha256'])
|
||||
# This function is executed in a separate preparation/integrity CPU process.
|
||||
for p in (AQ, AP, LAB): sys.path.insert(0,str(p))
|
||||
old = load_source('_normal_previous_integrity',AQ/'prepare_execution.py',ar['source_sha256'][str(AQ/'prepare_execution.py')])
|
||||
prior = old.integrity()
|
||||
helper = load_source('_normal_AQ_seal_reader', MODEL.parent/'pn-recruitment-audit-v1/publication.py',
|
||||
'7a79c499098b74163e7bb16adabcbc54e7069dafa204d0b99c7f4c03d79f8016')
|
||||
sealed = helper.verify_seal(AQ_EXP)
|
||||
require(read(AQ_EXP/'audit/final-status.json')['status'] ==
|
||||
'PASS-EXACT-UPDATED-BOUNDARY-ENGINEERING-NOT-LEARNING','AQ gate differs')
|
||||
return dict(complete=True,prior=prior,AQ=sealed,old_experiments_reexecuted=False,
|
||||
frozen_five_reexecuted=False,scope='actual historical seal bytes reverified, preserved numerical evidence; not a new numerical trial')
|
||||
|
||||
def resource_policy():
|
||||
"""Engineering ceiling, not a measured all-condition forecast or stop-for-success."""
|
||||
return dict(root=str(EXP),output_cap_bytes=256*1024**3,minimum_free_reserve_bytes=100*1024**3,
|
||||
child_timeout_seconds=1800,workflow_timeout_seconds=21*86400,max_uniform_draws=10_000_000,
|
||||
next_child_headroom_bytes=4*1024**3,
|
||||
execution='serial_single_4090',no_automatic_retry=True,
|
||||
forecast_scope='rough planning arithmetic from one AQ warm training cycle and one probe; not condition-complete measurement',
|
||||
AQ_measured_training_cycle_seconds=24.771224757998425,AQ_measured_probe_seconds=10.394962482001574,
|
||||
AQ_linear_wall_scenario_seconds=30000*24.771224757998425+3920*10.394962482001574,
|
||||
uncertainties=['startup and materialization','event-dependent output size','all control/DAN/odor activity',
|
||||
'ledger growth','shared service contention','final full integrity audit'],
|
||||
cap_or_timeout_policy='preserve all outputs, stop incomplete; no shortening epochs or selecting favorable outcomes')
|
||||
|
||||
def prepare():
|
||||
require(sys.dont_write_bytecode and unlinked(EXP).is_dir() and not any(EXP.iterdir()), 'Exact new empty EXP and -B required')
|
||||
files=sorted(MODEL.iterdir())
|
||||
require(files and all(p.is_file() and not p.is_symlink() and p.suffix in ('.py','.md') for p in files), 'Source-only model directory')
|
||||
sources={str(p):digest(p) for p in files}
|
||||
commit=subprocess.check_output(['git','-C',str(ROOT),'rev-parse','HEAD']).decode().strip()
|
||||
for path,sha in sources.items():
|
||||
blob=subprocess.check_output(['git','-C',str(ROOT),'show',commit+':'+Path(path).relative_to(ROOT).as_posix()])
|
||||
require(hashlib.sha256(blob).hexdigest()==sha, 'Uncommitted source '+path)
|
||||
budget=resource_policy()
|
||||
budget['registered_utc']=datetime.now(timezone.utc).isoformat()
|
||||
budget['not_after_utc']=(datetime.now(timezone.utc)+timedelta(seconds=budget['workflow_timeout_seconds'])).isoformat()
|
||||
require(shutil.disk_usage(EXP).free >= budget['output_cap_bytes']+budget['minimum_free_reserve_bytes'], 'Insufficient reserved capacity')
|
||||
for name in ('protocol/source-snapshot','inputs/static','jobs','cases','runs','updates','validation','results','receipts','logs','audit','regression'):
|
||||
unlinked(EXP/name).mkdir(parents=True)
|
||||
tests=subprocess.run([sys.executable,'-B',str(MODEL/'run_cpu_tests.py'),'--output',str(EXP/'audit/cpu-tests.json')],
|
||||
capture_output=True,text=True,timeout=1800,env={**dict(__import__('os').environ),'CUDA_VISIBLE_DEVICES':''})
|
||||
save(EXP/'audit/cpu-tests.process.json',dict(exit_code=tests.returncode,stdout=tests.stdout,stderr=tests.stderr,
|
||||
actual_parent_observation=True))
|
||||
require(tests.returncode==0 and read(EXP/'audit/cpu-tests.json')['pass_all'] is True,
|
||||
'CPU/source tests failed; no sampler or brain started')
|
||||
# Old integrity readers may own a private R/C module graph. Keep them in an
|
||||
# exec-isolated CPU process, never the table/registration interpreter.
|
||||
integrity_command=[sys.executable,'-B',str(MODEL/'normal_prepare.py'),'integrity',
|
||||
'--output',str(EXP/'regression/integrity-before.json')]
|
||||
checked=subprocess.run(integrity_command,capture_output=True,text=True,timeout=1800,
|
||||
env={**dict(__import__('os').environ),'CUDA_VISIBLE_DEVICES':''})
|
||||
save(EXP/'regression/integrity-before.process.json',dict(argv=integrity_command,exit_code=checked.returncode,
|
||||
stdout=checked.stdout,stderr=checked.stderr,actual_parent_observation=True))
|
||||
require(checked.returncode==0,'Historical integrity child failed; preserve artifacts')
|
||||
before=read(EXP/'regression/integrity-before.json');require(before['complete'] is True,'Integrity child incomplete')
|
||||
aq=read(AQ_EXP/'protocol/preregistered.json')
|
||||
full=read(PLAN.AO_TRIAL_PATH)
|
||||
require(digest(PLAN.AO_TRIAL_PATH)==PLAN.AO_TRIAL_FILE_SHA256,'Original full plan pin differs')
|
||||
evaluation=PLAN.expand_pinned_evaluation(full)
|
||||
plan=PLAN.build_normal_plan(full,evaluation)
|
||||
from normal_inputs import derive_rates, inventory_from_plan, PINS, dependencies
|
||||
rate_tables,rate_audit=derive_rates()
|
||||
inputs=inventory_from_plan(plan)
|
||||
template_path=AP_EXP/'cases/D1--reference--epoch-001/spec.json'
|
||||
authority_path=AP_EXP/'jobs/D1--reference--epoch-001.authority.json'
|
||||
template=read(template_path); epoch=read(authority_path)
|
||||
pinned={**aq['input_sha256'],**aq['source_sha256'],**aq['prepared_file_sha256']}
|
||||
for path in (template_path,authority_path,AO_EXP/'inputs/static/populations.npz'):
|
||||
require(str(path) in pinned and digest(path)==pinned[str(path)],'Original template/population not pinned')
|
||||
for path in sources:
|
||||
with Path(path).open('rb') as i,(EXP/'protocol/source-snapshot'/Path(path).name).open('xb') as o:shutil.copyfileobj(i,o)
|
||||
save(EXP/'protocol/normal-plan.json',plan)
|
||||
save(EXP/'protocol/evaluation-policy.json',evaluation['config'])
|
||||
save(EXP/'protocol/input-inventory.json',inputs)
|
||||
save(EXP/'protocol/case-template.json',template)
|
||||
# Freeze scientific predicates before any new CS sample or outcome.
|
||||
gate_sources={str(AQ/'learning_gates.py'):'8ae9bcb77fe14dbdda164f86ffdbfc1e2976be752766ef526777577223b4dd99',
|
||||
str(LAB/'metrics.py'):'47319e21db3c8b030b1bafbf0703cd86fb588d23bb29436accbacdba73d08c3c'}
|
||||
verify(gate_sources)
|
||||
save(EXP/'protocol/gates.json',dict(source_sha256=gate_sources,all_eight_cells_required=True,
|
||||
same_replicate_conjunction_at_least=3,training_replicates=5,terminal_checkpoint=50,
|
||||
normal_failure_prevents_followups=True,intermediate_checkpoints_cannot_rescue_terminal=True,
|
||||
downstream_policy='nonMBONDownstream-pre-outcome-operationalization-v1',
|
||||
H_mapping='each-DAN-control-source-separately-both-pass-v1',
|
||||
physiological_and_matched_energy_not_pooled=True,unknown_compartments_not_guessed=True))
|
||||
save(EXP/'inputs/static/rate-audit.json',rate_audit)
|
||||
for key,table in rate_tables.items():save_npz(EXP/f'inputs/static/{key}.npz',table)
|
||||
populations,pop_audit=readout_populations(AO_EXP/'inputs/static/populations.npz')
|
||||
save_npz(EXP/'inputs/static/readout-populations.npz',populations)
|
||||
save(EXP/'inputs/static/readout-population-binding.json',pop_audit)
|
||||
# Actual consumed neural dependency closure, all inherited byte pins.
|
||||
required=runtime_array_paths(template)
|
||||
require(required <= pinned.keys(), 'Consumed runtime arrays missing inherited pins: '+str(sorted(required-pinned.keys())))
|
||||
original_sources={p:s for p,s in epoch['frozen_inputs'].items() if p.startswith(str(ROOT/'models/male-cns-lif/') )
|
||||
and ('author-' in p or 'apl-timing-lab-v1/' in p)}
|
||||
runtime={p:pinned[p] for p in required}
|
||||
runtime.update(original_sources)
|
||||
roles={k:v for k,v in epoch['files'].items() if k not in ('spec','requests','state','overlay_before','overlay_manifest_before')}
|
||||
runtime.update({v['path']:v['sha256'] for v in roles.values()})
|
||||
save(EXP/'protocol/epoch-template.json',dict(schema=epoch['schema'],files=roles,frozen_inputs=runtime))
|
||||
static={str(LAB/n):s for n,s in {**PLAN.SOURCE_PINS,**PINS}.items()}
|
||||
static.update({str(ROOT/p):s for p,s in rate_audit['original_source_sha256'].items()})
|
||||
external={**runtime,**static,**gate_sources,**pop_audit['source_sha256'],**{str(AQ_EXP/p):s for p,s in AQ_ANCHORS.items()},
|
||||
str(PLAN.AO_TRIAL_PATH):PLAN.AO_TRIAL_FILE_SHA256,str(AP/'isolated_workers.py'):AP_SHA,
|
||||
str(authority_path):pinned[str(authority_path)],str(template_path):pinned[str(template_path)],
|
||||
str(AO_EXP/'inputs/static/populations.npz'):pinned[str(AO_EXP/'inputs/static/populations.npz')],
|
||||
str(AQ/'validate_update_cpu.py'):aq['source_sha256'][str(AQ/'validate_update_cpu.py')]}
|
||||
for name in ('conditioning_epoch.py','conditioning_preflight_compare.py','engineering_compare.py'):
|
||||
path=str(LAB/name);require(path in pinned,'Missing original verifier source pin');external[path]=pinned[path]
|
||||
zero=aq['initial_overlay']
|
||||
external.update({p:digest(p) for p in zero.values()})
|
||||
verify(external)
|
||||
prepared={p:row['sha256'] for p,row in inventory(EXP).items()}
|
||||
reg=dict(schema='normal-conditioning-registration-v1',scientific_scope='normal-acquisition-only',
|
||||
subsequent_assays_authorized=False,source_code_commit=commit,source_sha256=sources,input_sha256=external,
|
||||
static_input_sha256=static,runtime_input_sha256=runtime,prepared_sha256=prepared,budget=budget,
|
||||
initial_overlay=zero,population_file=str(AO_EXP/'inputs/static/populations.npz'),
|
||||
readout_population_file=str(EXP/'inputs/static/readout-populations.npz'),
|
||||
readout_population_binding_file=str(EXP/'inputs/static/readout-population-binding.json'),
|
||||
original_full_trial_plan=pin(PLAN.AO_TRIAL_PATH),normal_inventory=plan['inventory'],
|
||||
evidence_scope='AQ validates exact interface, not learning; this new registration admits actual normal outcomes',
|
||||
brain_parameters_changed=False,learning_success_claimed=False,
|
||||
execution_order='original fixed block/arm order; actual A/B baseline each arm; no outcome selection',
|
||||
biological_hypotheses='D18 branch; PAM15/PPL103 compartment hypotheses only, not all-PAM/PPL functional assignment',
|
||||
historical_integrity_scope=before['scope'],failure_policy='stop preserve partials, never auto retry',
|
||||
administrative_supervisor_directory=str(ROOT/'logs/phase4ar-normal-conditioning'),
|
||||
supervisor_logging_scope='outside immutable EXP ledger; real top-level exit and logs must be included by final outer auditor',
|
||||
full_plan_in_old_frozen_location=True,future_artifact_hashes_fabricated=False)
|
||||
save(EXP/'protocol/preregistered.json',reg)
|
||||
return digest(EXP/'protocol/preregistered.json')
|
||||
|
||||
if __name__=='__main__':
|
||||
p=argparse.ArgumentParser();p.add_argument('mode',choices=('prepare','integrity'));p.add_argument('--output')
|
||||
a=p.parse_args()
|
||||
if a.mode=='prepare':print('REGISTRATION_SHA256',prepare(),flush=True)
|
||||
else:
|
||||
require(a.output,'Exclusive report path required');save(a.output,historical_integrity())
|
||||
@@ -0,0 +1,341 @@
|
||||
"""Serial normal conditioning. Original R/E/U executables stay unchanged.
|
||||
|
||||
Every fresh brain trial is followed by original E and independent original-U
|
||||
recomputation in separate exec processes. Probes never run E or feed back.
|
||||
Only fully committed steps may be skipped on explicit resume. An uncommitted
|
||||
start, failed child or partial task always stops; no inferred OS exit or retry.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import argparse
|
||||
import copy
|
||||
from datetime import datetime, timezone
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
import traceback
|
||||
import numpy as np
|
||||
from normal_io import *
|
||||
from append_ledger import Ledger
|
||||
|
||||
def registration(expected):
|
||||
require(digest(EXP/'protocol/preregistered.json')==expected,'Registration hash differs')
|
||||
reg=read(EXP/'protocol/preregistered.json')
|
||||
require(reg['schema']=='normal-conditioning-registration-v1' and reg['scientific_scope']=='normal-acquisition-only'
|
||||
and reg['subsequent_assays_authorized'] is False,'Wrong authority')
|
||||
verify(reg['source_sha256']);verify(reg['input_sha256']);verify(reg['prepared_sha256'])
|
||||
return reg
|
||||
|
||||
def derive_spec(original,task,*,budget_root,output_cap):
|
||||
require(original['kind']=='fullgraph' and original['dt_ms']==.1 and original['apl_delay_steps']==18 and
|
||||
original['precision']=='float64' and original['apl_precision']=='float32' and original['record_history'] is False,
|
||||
'Original fixed D18 spec required')
|
||||
require(task['steps']==1200 and task['kind'] in ('train','probe'),'Wrong task')
|
||||
allowed=('validation_cohort','odor_index','expected_external_events','training','cs_input_seed','cs_input_seed_bits',
|
||||
'seed_scope','odor_id','odor_name','source_panel_row','source_panel_split','rate_sum_hz','target_count',
|
||||
'expected_CS_requests','CS_window','outer_epoch_id','outer_arm','outer_protocol')
|
||||
result={k:copy.deepcopy(v) for k,v in original.items() if k not in allowed}
|
||||
result.update(name=task_key(task),steps=1200,duration_ms=120.,max_steps=1200,budget_root=str(budget_root),
|
||||
output_budget_bytes=output_cap,mode=task['mode'],within_trial_weight_updates=False,
|
||||
outer_protocol='normal-acquisition-v1',outer_task_id=task['task_id'],outer_arm=task['arm'])
|
||||
# The frozen independent reset-control seed is retained, not derived from CS.
|
||||
require(result['seed']==original['seed'],'Reset seed changed')
|
||||
return result
|
||||
|
||||
def compose_requests(cs,dan,task,inputs):
|
||||
require(task['steps']==1200,'Only normal120ms tasks')
|
||||
if task['kind']=='probe':
|
||||
recipe=task['recipe'];require(recipe['US_requested'] is False and recipe['D_command']==0 and
|
||||
recipe['weight_updates_enabled'] is False and task['feedback_to_training_or_idle'] is False,'Probe command differs')
|
||||
nodes=np.empty(0,np.int32)
|
||||
else:
|
||||
recipe=task['recipe'];us=recipe['us']
|
||||
require(us['nominal_slot_tick']==900 and us['rng_seed'] is None and us['rng_draws']==0 and
|
||||
((us['requested'] is True and us['tick']==900) or (us['requested'] is False and us['tick'] is None)),
|
||||
'Scheduled artificial US differs')
|
||||
require(recipe['D_command']==(1. if us['requested'] and task['arm']!='d_zero' else 0.) and
|
||||
recipe['update_enabled'] is (task['arm']!='frozen'),'D/update command differs')
|
||||
require(dan.dtype==np.int32 and dan.ndim==1 and len(dan) in (2,4) and np.all(dan[1:]>dan[:-1]),'Bound DAN IDs required')
|
||||
nodes=dan.copy() if us['requested'] else np.empty(0,np.int32)
|
||||
us=dict(tick=np.full(len(nodes),900,np.int32),neuron_idx=nodes)
|
||||
composed=inputs.merge_requests(cs,us,steps=1200,conflict_policy='error')
|
||||
return composed,us
|
||||
|
||||
class Workflow:
|
||||
def __init__(self,sha):
|
||||
self.sha=sha;self.reg=registration(sha);self.start=time.perf_counter()
|
||||
require(not (EXP/'audit/stopped.json').exists() and not (EXP/'manifest.json').exists(), 'Stopped or sealed phase cannot run')
|
||||
self.plan=read(EXP/'protocol/normal-plan.json');self.input_plan=read(EXP/'protocol/input-inventory.json')
|
||||
self.tasks={x['task_id']:x for x in self.plan['tasks']}
|
||||
self.h=load_source('_normal_AP_helpers',AP/'isolated_workers.py',AP_SHA)
|
||||
self.inputs=load_source('_normal_request_composer',LAB/'conditioning_inputs.py',self.reg['static_input_sha256'][str(LAB/'conditioning_inputs.py')])
|
||||
self.metric=load_source('_normal_CPU_state_validation',LAB/'metrics.py',self.reg['input_sha256'][str(LAB/'metrics.py')])
|
||||
self.nodes=np.load(Path(read(EXP/'protocol/case-template.json')['graph_dir'])/'nodes.npy',allow_pickle=False)
|
||||
self.populations=npz(self.reg['population_file'])
|
||||
initial={Path(p).relative_to(EXP).as_posix():identity(p) for p in self.reg['prepared_sha256']}
|
||||
initial['protocol/preregistered.json']=identity(EXP/'protocol/preregistered.json')
|
||||
self.ledger=Ledger(EXP,sha,initial,self.reg['budget']['output_cap_bytes'],self.reg['budget']['minimum_free_reserve_bytes'])
|
||||
status=self.ledger.inspect();require(not status['uncommitted_entry_ids'],'Uncommitted OS state unknown; no automatic retry')
|
||||
self.completed=set(status['entry_ids']);self.expected=[]
|
||||
|
||||
def basepins(self):
|
||||
return {**self.reg['runtime_input_sha256'],str(EXP/'protocol/preregistered.json'):self.sha}
|
||||
|
||||
def immutable_pin(self,path):
|
||||
path=unlinked(path);rel=path.relative_to(EXP).as_posix()
|
||||
require(rel in self.ledger._tracked and identity(path)==self.ledger._tracked[rel],
|
||||
'Consumed immutable file differs from committed bytes: '+rel)
|
||||
return dict(path=str(path),sha256=self.ledger._tracked[rel]['sha256'])
|
||||
|
||||
def budget(self):
|
||||
require(time.perf_counter()-self.start < self.reg['budget']['workflow_timeout_seconds'],'Invocation wall cap exceeded')
|
||||
require(datetime.now(timezone.utc)<datetime.fromisoformat(self.reg['budget']['not_after_utc']),
|
||||
'Registered absolute deadline exceeded; resume cannot reset wall allowance')
|
||||
require(shutil.disk_usage(EXP).free>=self.reg['budget']['minimum_free_reserve_bytes'],'Free space reserve exceeded')
|
||||
# Running totals account only committed payload, ledger and shared build.
|
||||
# Each child also gets a fresh per-child output allowance; full tree at final.
|
||||
accounting=self.ledger._budget()
|
||||
require(accounting['total_accounted_bytes']+self.reg['budget']['next_child_headroom_bytes'] <=
|
||||
self.reg['budget']['output_cap_bytes'],'No registered headroom for another complete child')
|
||||
|
||||
def launch(self,name,job,argv,outputs,*,pre_outputs=(),post=None,ap=False):
|
||||
self.expected.append(name)
|
||||
require(name not in self.completed,'Internal attempt to rerun committed job')
|
||||
self.budget()
|
||||
unlinked(EXP/'receipts'/name).mkdir()
|
||||
jobfile=EXP/f'jobs/{name}.json';save(jobfile,job);jobsha=digest(jobfile)
|
||||
argv=[*argv]
|
||||
if ap:argv+=['--job',str(jobfile),'--job-sha256',jobsha]
|
||||
start=self.ledger.begin(name,jobfile,dict(kind=job['kind']))
|
||||
stdout=EXP/f'logs/{name}.stdout.log';stderr=EXP/f'logs/{name}.stderr.log'
|
||||
process=EXP/f'receipts/{name}/process.json'
|
||||
started=time.perf_counter();rc=None;timed=False;launch_error=None
|
||||
env=dict(os.environ);env['PYTHONDONTWRITEBYTECODE']='1'
|
||||
if job['kind'] not in ('brain','sample'):env['CUDA_VISIBLE_DEVICES']=''
|
||||
with unlinked(stdout).open('xb') as out,unlinked(stderr).open('xb') as err:
|
||||
try:rc=subprocess.run(argv,cwd=MODEL,env=env,stdout=out,stderr=err,
|
||||
timeout=self.reg['budget']['child_timeout_seconds']).returncode
|
||||
except subprocess.TimeoutExpired:timed=True
|
||||
except OSError as error:launch_error=type(error).__name__+': '+str(error)
|
||||
base=dict(entry_id=name,registration_sha256=self.sha,job_sha256=jobsha,argv=argv,
|
||||
exit_code=rc,timed_out=timed,exit_observed_by_parent=rc is not None or timed,launch_error=launch_error,
|
||||
child_wall_seconds=time.perf_counter()-started,observed_utc=datetime.now(timezone.utc).isoformat(),
|
||||
stdout_sha256=digest(stdout),stderr_sha256=digest(stderr))
|
||||
try:
|
||||
require(type(rc)is int and rc==0 and not timed,'Child failed; retain outputs and stop')
|
||||
verify(job['input_sha256'])
|
||||
if ap:
|
||||
receipt=read(job['receipt_file'])
|
||||
require(receipt['schema']=='phase4ap-isolated-worker-receipt-v1' and receipt['complete'] is True and
|
||||
receipt['job_sha256']==jobsha and receipt['registration_sha256']==self.sha and
|
||||
receipt['kind']==job['kind'] and receipt['job_id']==name,'Actual child receipt differs')
|
||||
expected={**job['input_sha256'],str(jobfile):jobsha,str(AP/'isolated_workers.py'):AP_SHA,
|
||||
**{v['path']:v['sha256'] for v in job['sources'].values()}}
|
||||
require(receipt['verified_input_sha256']==expected,'Worker input closure differs')
|
||||
actual={str(Path(p).relative_to(job['output_dir'])):v['sha256'] for p,v in inventory(Path(job['output_dir'])).items()}
|
||||
require(actual==receipt['output_files_sha256'],'Worker output inventory differs')
|
||||
require(digest(job['receipt_file']+'.attempt.json')==receipt['attempt_sha256'],'Attempt changed')
|
||||
if post is not None:post()
|
||||
base.update(complete=True,end_to_end_seconds=time.perf_counter()-started)
|
||||
save(process,base)
|
||||
files=[*pre_outputs,jobfile,stdout,stderr,process]
|
||||
for p in outputs:
|
||||
p=Path(p);files.extend(Path(x) for x in inventory(p)) if p.is_dir() else files.append(p)
|
||||
outgoing={str(p):identity(p) for p in files}
|
||||
incoming={p:identity(p) for p in job['input_sha256']}
|
||||
incoming[str(jobfile)]=identity(jobfile)
|
||||
self.ledger.append(name,incoming,outgoing,dict(job_file=str(jobfile),process_receipt_file=str(process),
|
||||
observed_returncode=rc,scope='actual serial child exit and immutable artifact verification'))
|
||||
self.completed.add(name)
|
||||
print(json.dumps(dict(complete=True,entry_id=name,wall_seconds=base['end_to_end_seconds']),sort_keys=True),flush=True)
|
||||
except BaseException as error:
|
||||
if not process.exists():save(process,dict(base,complete=False,error=str(error)))
|
||||
raise
|
||||
|
||||
def input_generation(self):
|
||||
name='input-generation'
|
||||
if name in self.completed:self.expected.append(name);return
|
||||
pins={**self.reg['source_sha256'],**self.reg['static_input_sha256'],
|
||||
**{p:s for p,s in self.reg['prepared_sha256'].items() if '/inputs/static/' in p or p.endswith('/input-inventory.json')},
|
||||
str(EXP/'protocol/preregistered.json'):self.sha}
|
||||
job=dict(kind='sample',registration_sha256=self.sha,input_sha256=pins)
|
||||
def validate_sample():
|
||||
report=read(EXP/'receipts/input-generation.json')
|
||||
require(report['complete'] is True and report['registration_sha256']==self.sha and
|
||||
set(report['inputs'])==set(self.input_plan['descriptors']) and report['descriptors']==4080,
|
||||
'Incomplete original sampling inventory')
|
||||
for key,d in self.input_plan['descriptors'].items():
|
||||
f=EXP/f'inputs/generated/{key}.npz';a=EXP/f'inputs/generated/{key}.json'
|
||||
audit=read(a)
|
||||
require(audit['descriptor']==d and audit['requests_sha256']==digest(f) and
|
||||
report['inputs'][key]==dict(requests=pin(f),audit=pin(a)), 'Saved sampler binding differs')
|
||||
self.inputs.validate_requests(npz(f),1200)
|
||||
self.launch(name,job,[sys.executable,'-B',str(MODEL/'normal_inputs.py'),'--registration-sha256',self.sha],
|
||||
[EXP/'inputs/generated',EXP/'receipts/input-generation.json'],post=validate_sample)
|
||||
|
||||
def overlay(self,task):
|
||||
self.overlay_dependency_pins={}
|
||||
dependency=task['delta_dependency']
|
||||
if dependency==dict(kind='zero',source=None):return copy.deepcopy(self.reg['initial_overlay'])
|
||||
require(dependency['kind']=='epoch_delta_after' and dependency['source'].endswith('/delta-after'),'Unknown delta dependency')
|
||||
previous=self.tasks[dependency['source'][:-len('/delta-after')]]
|
||||
key=task_key(previous);require(key+'--verify' in self.completed,'Previous real E+CPU validation missing')
|
||||
result_path=EXP/f'results/{key}.json'
|
||||
def committed(path):
|
||||
checked=self.immutable_pin(path)
|
||||
self.overlay_dependency_pins[checked['path']]=checked['sha256']
|
||||
committed(result_path);record=read(result_path)
|
||||
require(record['complete'] is True and record['task']==previous and previous['kind']=='train' and
|
||||
all(previous[k]==task[k] for k in ('block_id','arm')),'Delta cannot cross unrelated branch')
|
||||
validation=Path(record['cpu_validation']['path']);committed(validation)
|
||||
require(digest(validation)==record['cpu_validation']['sha256'],'CPU receipt changed')
|
||||
valid=read(validation)
|
||||
committed(Path(record['cpu_process_receipt_path']))
|
||||
process=read(record['cpu_process_receipt_path'])
|
||||
require(process['complete'] is True and type(process['exit_code']) is int and process['exit_code']==0 and
|
||||
process['entry_id']==key+'--verify' and process['registration_sha256']==self.sha,
|
||||
'Previous CPU exit missing')
|
||||
for role,filename,field in (('overlay_file','delta-after.npz','after_overlay_sha256'),
|
||||
('overlay_manifest','overlay-manifest.json','after_manifest_sha256')):
|
||||
path=Path(record['after_overlay'][role]);committed(path)
|
||||
require(path==Path(record['update_dir'])/filename and digest(path)==valid[field],
|
||||
'Next installed delta is not the actual independently verified output')
|
||||
return copy.deepcopy(record['after_overlay'])
|
||||
|
||||
def prepare_case(self,task):
|
||||
key=task_key(task);case=unlinked(EXP/'cases'/key);case.mkdir()
|
||||
template_file=EXP/'protocol/case-template.json'
|
||||
checked=self.immutable_pin(template_file)
|
||||
self.case_dependency_pins={checked['path']:checked['sha256'],
|
||||
self.reg['population_file']:self.reg['input_sha256'][self.reg['population_file']]}
|
||||
template=read(template_file)
|
||||
spec=derive_spec(template,task,budget_root=EXP,output_cap=self.reg['budget']['output_cap_bytes'])
|
||||
csid=self.input_plan['task_inputs'][task['task_id']]
|
||||
if csid is None:cs=dict(tick=np.empty(0,np.int32),neuron_idx=np.empty(0,np.int32));cs_source=None
|
||||
else:
|
||||
cs_source=EXP/f'inputs/generated/{csid}.npz'
|
||||
audit_file=EXP/'inputs/generated'/(csid+'.json')
|
||||
for path in (cs_source,audit_file):
|
||||
checked=self.immutable_pin(path);self.case_dependency_pins[checked['path']]=checked['sha256']
|
||||
generated=read(audit_file)
|
||||
require(generated['descriptor']==self.input_plan['descriptors'][csid] and
|
||||
generated['requests_sha256']==digest(cs_source),'Saved shared CS changed')
|
||||
cs=npz(cs_source)
|
||||
combined,us=compose_requests(cs,self.populations[task['dan_type']],task,self.inputs)
|
||||
save(case/'spec.json',spec);save_npz(case/'requests.npz',combined['requests'])
|
||||
save_npz(case/'cs_requests.npz',cs);save_npz(case/'us_requests.npz',us)
|
||||
save_npz(case/'source-mask.npz',dict(source_mask=combined['source_mask']))
|
||||
save(case/'input-binding.json',dict(task_id=task['task_id'],CS_source=None if cs_source is None else pin(cs_source),
|
||||
CS_descriptor_id=csid,composition=combined['audit'],DAN_type=task['dan_type'],
|
||||
DAN_membership_sha256=hashlib.sha256(self.populations[task['dan_type']].tobytes()).hexdigest(),
|
||||
population_file=pin(self.reg['population_file']),artificial_US_not_dopamine_concentration=True))
|
||||
return case
|
||||
|
||||
def ap_job(self,name,kind,output,*,case=None,overlay=None,authority=None):
|
||||
pins=self.basepins()
|
||||
job=dict(schema='phase4ap-isolated-worker-job-v1',job_id=name,kind=kind,registration_sha256=self.sha,
|
||||
worker_sha256=AP_SHA,output_dir=str(output),receipt_file=str(EXP/f'receipts/{name}/worker.json'))
|
||||
if kind=='brain':
|
||||
pins.update(self.overlay_dependency_pins)
|
||||
pins.update(self.case_dependency_pins)
|
||||
for p in (case/'spec.json',case/'requests.npz',overlay['overlay_file'],overlay['overlay_manifest']):pins[str(p)]=digest(p)
|
||||
job.update(case_dir=str(case),build_root=str(EXP/'extension-build'),**overlay,diagnostic_mode='light',
|
||||
admission=dict(gpu_uuid=GPU,comfy_queue_urls=list(self.h.COMFY_URLS)),
|
||||
sources={n:dict(path=str(LAB/(n+'.py')),sha256=self.h.SOURCE_PINS[n]) for n in ('runtime_light','runtime_continuation')})
|
||||
else:
|
||||
auth=read(authority);pins[str(authority)]=digest(authority)
|
||||
pins.update({v['path']:v['sha256'] for v in auth['files'].values()})
|
||||
pins.update(auth['frozen_inputs']);pins[str(Path(auth['checkpoint_dir'])/'checkpoint-manifest.json')]=auth['checkpoint_manifest_sha256']
|
||||
job.update(authority_file=str(authority),authority_sha256=digest(authority),
|
||||
sources={'conditioning_epoch':dict(path=str(LAB/'conditioning_epoch.py'),sha256=self.h.SOURCE_PINS['conditioning_epoch'])})
|
||||
job['input_sha256']=pins;return job
|
||||
|
||||
def brain_verify(self,task,case,output):
|
||||
summary=read(output/'summary.json');state=npz(output/'state.npz')
|
||||
checked=self.metric.validate_state(state,nodes=self.nodes,steps=1200)
|
||||
require(summary['all_finite'] is True and summary['steps']==1200 and summary['diagnostic_mode']=='light','Nonfinite/incomplete brain')
|
||||
require(int(state['counts'].sum())==summary['total_spikes'],'Spike event/count mismatch')
|
||||
manifest=read(output/'checkpoint-manifest.json')
|
||||
for rel,sha in manifest['files_sha256'].items():require(digest(output/rel)==sha,'Checkpoint payload changed')
|
||||
return dict(complete=True,state_raw_sha256=checked['hashes'],finite=True,
|
||||
checkpoint_manifest_sha256=digest(output/'checkpoint-manifest.json'),task_id=task['task_id'])
|
||||
|
||||
def task(self,task):
|
||||
key=task_key(task);brain=key+'--brain';up=key+'--update';cpu=key+'--verify'
|
||||
planned=[brain,up,cpu] if task['kind']=='train' else [brain]
|
||||
if all(x in self.completed for x in planned):self.expected.extend(planned);return
|
||||
require(not any(x in self.completed for x in planned),'Partially completed task: preserve and inspect; no implicit replay')
|
||||
overlay=self.overlay(task);case=self.prepare_case(task);output=EXP/'runs'/key
|
||||
record=dict(schema='normal-task-result-v1',complete=True,registration_sha256=self.sha,task=task,
|
||||
checkpoint_dir=str(output),overlay_before=overlay,brain_process_receipt_path=str(EXP/f'receipts/{brain}/process.json'))
|
||||
def after_brain():
|
||||
record['brain_audit']=self.brain_verify(task,case,output)
|
||||
record['checkpoint_manifest_sha256']=digest(output/'checkpoint-manifest.json')
|
||||
# Parent process receipt is produced later and is bound by the ledger,
|
||||
# avoiding a self-reference in a result written before process exit audit.
|
||||
if task['kind']=='probe':save(EXP/f'results/{key}.json',record)
|
||||
job=self.ap_job(brain,'brain',output,case=case,overlay=overlay)
|
||||
outs=[output,Path(job['receipt_file']),Path(job['receipt_file']+'.attempt.json')]
|
||||
if task['kind']=='probe':outs.append(EXP/f'results/{key}.json')
|
||||
self.launch(brain,job,[sys.executable,'-B',str(AP/'isolated_workers.py'),'brain'],outs,
|
||||
pre_outputs=[Path(p) for p in inventory(case)],post=after_brain,ap=True)
|
||||
if task['kind']=='probe':return
|
||||
template_pin=self.immutable_pin(EXP/'protocol/epoch-template.json')
|
||||
template=read(template_pin['path']);auth=copy.deepcopy(template)
|
||||
r=task['recipe'];auth.update(epoch_id=task['task_id'],diagnostic_mode='light',checkpoint_dir=str(output),
|
||||
checkpoint_manifest_sha256=digest(output/'checkpoint-manifest.json'),
|
||||
command=dict(steps=1200,compartment=task['compartment_verbatim'],us_tick=r['us']['tick'],d_command=r['D_command'],
|
||||
frozen=not r['update_enabled'],trace_backend='torch'))
|
||||
for role,path in dict(spec=case/'spec.json',requests=case/'requests.npz',state=output/'state.npz',
|
||||
overlay_before=overlay['overlay_file'],overlay_manifest_before=overlay['overlay_manifest']).items():auth['files'][role]=pin(path)
|
||||
authority=EXP/f'jobs/{key}.authority.json';save(authority,auth);update=EXP/'updates'/key
|
||||
job=self.ap_job(up,'update',update,authority=authority)
|
||||
job['input_sha256'][template_pin['path']]=template_pin['sha256']
|
||||
for path in (EXP/f'receipts/{brain}/process.json',EXP/f'receipts/{brain}/worker.json'):
|
||||
checked=self.immutable_pin(path);job['input_sha256'][checked['path']]=checked['sha256']
|
||||
self.launch(up,job,[sys.executable,'-B',str(AP/'isolated_workers.py'),'update'],
|
||||
[update,Path(job['receipt_file']),Path(job['receipt_file']+'.attempt.json')],pre_outputs=[authority],ap=True)
|
||||
out=unlinked(EXP/'validation'/key);out.mkdir();validation=out/'validation.json'
|
||||
script=AQ/'validate_update_cpu.py';verify({str(script):self.reg['input_sha256'][str(script)]})
|
||||
pins={**job['input_sha256'],str(script):self.reg['input_sha256'][str(script)]}
|
||||
for name in ('conditioning_epoch.py','conditioning_preflight_compare.py','engineering_compare.py'):
|
||||
path=str(LAB/name);pins[path]=self.reg['input_sha256'][path]
|
||||
pins.update({p:v['sha256'] for p,v in inventory(update).items()})
|
||||
job=dict(kind='cpu_verify',registration_sha256=self.sha,input_sha256=pins,authority_file=str(authority),
|
||||
authority_sha256=digest(authority),update_dir=str(update),chain_sha256=digest(update/'chain-receipt.json'),
|
||||
receipt_file=str(validation),validator_sha256=self.reg['input_sha256'][str(script)])
|
||||
def after_cpu():
|
||||
valid=read(validation)
|
||||
require(valid['complete'] is True and valid['frozen_U_verify_receipt_recomputed'] is True and
|
||||
valid['actual_sealed_events_used'] is True and valid['after_overlay_sha256']==digest(update/'delta-after.npz') and
|
||||
valid['epoch_authority_sha256']==digest(authority),'Independent update verification differs')
|
||||
if task['arm'] in ('d_zero','frozen','cs_only'):
|
||||
require(not npz(update/'delta-after.npz')['plastic_delta_mv'].view(np.uint32).any(),'Zero-update control became nonzero')
|
||||
record.update(epoch_authority=pin(authority),update_dir=str(update),cpu_validation=pin(validation),
|
||||
after_overlay=dict(overlay_file=str(update/'delta-after.npz'),overlay_manifest=str(update/'overlay-manifest.json')),
|
||||
update_process_receipt_path=str(EXP/f'receipts/{up}/process.json'),
|
||||
cpu_process_receipt_path=str(EXP/f'receipts/{cpu}/process.json'))
|
||||
save(EXP/f'results/{key}.json',record)
|
||||
self.launch(cpu,job,[sys.executable,'-B',str(script),'--authority',str(authority),'--authority-sha256',digest(authority),
|
||||
'--update-dir',str(update),'--chain-sha256',digest(update/'chain-receipt.json'),'--receipt',str(validation)],
|
||||
[out,EXP/f'results/{key}.json'],post=after_cpu)
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
self.input_generation()
|
||||
for task in self.plan['tasks']:self.task(task)
|
||||
report=self.ledger.final_verify(self.expected)
|
||||
require(report['pass_all'],'Final ledger coverage/integrity failed')
|
||||
save(EXP/'audit/execution-complete.json',dict(complete=True,registration_sha256=self.sha,
|
||||
inventory=self.plan['inventory'],ledger=report,learning_success_claimed=False,
|
||||
next='independent scientific analysis and frozen integrity, no subsequent assay'))
|
||||
except BaseException as error:
|
||||
if not (EXP/'audit/stopped.json').exists():save(EXP/'audit/stopped.json',dict(complete=False,
|
||||
registration_sha256=self.sha,error_type=type(error).__name__,error=str(error),
|
||||
traceback=traceback.format_exc(),partial_files_preserved=True,automatic_retry=False))
|
||||
raise
|
||||
|
||||
if __name__=='__main__':
|
||||
p=argparse.ArgumentParser();p.add_argument('--registration-sha256',required=True)
|
||||
Workflow(p.parse_args().registration_sha256).run()
|
||||
@@ -0,0 +1,30 @@
|
||||
"""Exclusive CPU/source test receipt. No scientific execution or CUDA allowed."""
|
||||
import argparse
|
||||
import io
|
||||
import os
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import time
|
||||
import unittest
|
||||
from normal_io import digest, save, require, MODEL
|
||||
|
||||
def run(output):
|
||||
require(sys.dont_write_bytecode,'Use -B')
|
||||
os.environ['CUDA_VISIBLE_DEVICES']=''
|
||||
before={p.name:digest(p) for p in MODEL.iterdir() if p.is_file()}
|
||||
suite=unittest.defaultTestLoader.discover(str(MODEL),pattern='test_*.py')
|
||||
text=io.StringIO();start=time.perf_counter()
|
||||
result=unittest.TextTestRunner(stream=text,verbosity=2).run(suite)
|
||||
after={p.name:digest(p) for p in MODEL.iterdir() if p.is_file()}
|
||||
no_neural_modules=not any(n in sys.modules for n in ('torch','runtime_light','conditioning_epoch'))
|
||||
success=result.wasSuccessful() and not result.skipped and before==after and no_neural_modules
|
||||
save(output,dict(schema='normal-CPU-tests-v1',pass_all=success,tests=result.testsRun,
|
||||
failures=len(result.failures),errors=len(result.errors),skips=len(result.skipped),
|
||||
source_sha256=before,sources_unchanged=before==after,wall_seconds=time.perf_counter()-start,
|
||||
stdout=text.getvalue(),fresh_process=True,CUDA_hidden=True,no_neural_modules=no_neural_modules,
|
||||
scope='CPU source and mock-process tests; not real GPU numerical or scientific evidence'))
|
||||
return success
|
||||
|
||||
if __name__=='__main__':
|
||||
p=argparse.ArgumentParser();p.add_argument('--output',required=True)
|
||||
sys.exit(0 if run(p.parse_args().output) else 1)
|
||||
@@ -0,0 +1,55 @@
|
||||
"""Detached parent supervisor, with real final exit receipts outside EXP.
|
||||
|
||||
Administrative stdout is separate from the immutable per-trial ledger. Launch
|
||||
is exclusive, never a retry policy. A launch PID is NOT a completion receipt.
|
||||
"""
|
||||
import argparse
|
||||
from datetime import datetime, timezone
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
from normal_io import *
|
||||
|
||||
CONTROL=ROOT/'logs/phase4ar-normal-conditioning'
|
||||
|
||||
def authority(sha):
|
||||
require(sys.dont_write_bytecode,'Use -B')
|
||||
require(digest(EXP/'protocol/preregistered.json')==sha,'Registration differs')
|
||||
reg=read(EXP/'protocol/preregistered.json');verify(reg['source_sha256'])
|
||||
require(reg['scientific_scope']=='normal-acquisition-only' and unlinked(CONTROL).is_dir(),'Wrong scope/control directory')
|
||||
require(not (EXP/'audit/stopped.json').exists() and not (EXP/'audit/execution-complete.json').exists(),
|
||||
'Stopped/completed phase cannot launch')
|
||||
return reg
|
||||
|
||||
def launch(sha):
|
||||
authority(sha)
|
||||
require(not any(CONTROL.iterdir()),'Control directory nonempty: inspect, do not retry')
|
||||
save(CONTROL/'launch-attempt.json',dict(registration_sha256=sha,started_utc=datetime.now(timezone.utc).isoformat(),
|
||||
complete=False,terminal_state='UNKNOWN',automatic_retry=False))
|
||||
command=[sys.executable,'-B',str(MODEL/'run_normal.py'),'supervise','--registration-sha256',sha]
|
||||
with unlinked(CONTROL/'stdout.log').open('xb') as out,unlinked(CONTROL/'stderr.log').open('xb') as err:
|
||||
process=subprocess.Popen(command,cwd=MODEL,stdin=subprocess.DEVNULL,stdout=out,stderr=err,start_new_session=True,
|
||||
env={**os.environ,'PYTHONDONTWRITEBYTECODE':'1'})
|
||||
record=dict(supervisor_pid=process.pid,argv=command,registration_sha256=sha,launch_observed=True,
|
||||
final_exit_observed=False,not_evidence_of_completion=True)
|
||||
save(CONTROL/'launch.json',record);return record
|
||||
|
||||
def supervise(sha):
|
||||
authority(sha)
|
||||
save(CONTROL/'supervisor-start.json',dict(pid=os.getpid(),registration_sha256=sha,
|
||||
started_utc=datetime.now(timezone.utc).isoformat(),complete=False))
|
||||
command=[sys.executable,'-B',str(MODEL/'normal_runner.py'),'--registration-sha256',sha]
|
||||
started=time.perf_counter();code=None;error=None
|
||||
try:code=subprocess.run(command,cwd=MODEL,stdin=subprocess.DEVNULL).returncode
|
||||
except BaseException as exc:error=type(exc).__name__+': '+str(exc)
|
||||
save(CONTROL/'exit.json',dict(registration_sha256=sha,argv=command,exit_code=code,
|
||||
final_exit_observed=type(code)is int,wall_seconds=time.perf_counter()-started,error=error,
|
||||
complete=code==0,learning_success_claimed=False,scientific_analysis_required=True))
|
||||
return 0 if code==0 else 1
|
||||
|
||||
if __name__=='__main__':
|
||||
parser=argparse.ArgumentParser();parser.add_argument('mode',choices=('launch','supervise'))
|
||||
parser.add_argument('--registration-sha256',required=True);args=parser.parse_args()
|
||||
if args.mode=='launch':print(canonical(launch(args.registration_sha256)),flush=True)
|
||||
else:sys.exit(supervise(args.registration_sha256))
|
||||
@@ -0,0 +1,241 @@
|
||||
"""Temporary filesystem tests only; no process/brain/GPU execution."""
|
||||
import copy
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import tempfile
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
import append_ledger as L
|
||||
|
||||
|
||||
def put(path, value):
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
path.write_bytes(value if type(value) is bytes else L.raw_json(value))
|
||||
return L.identity(path)
|
||||
|
||||
|
||||
class LedgerTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.temp=tempfile.TemporaryDirectory();self.addCleanup(self.temp.cleanup)
|
||||
self.root=Path(self.temp.name).resolve()/'normal';self.root.mkdir()
|
||||
self.reg=self.root/L.REGISTRATION; info=put(self.reg,{'only':'synthetic-registration'})
|
||||
self.initial={L.REGISTRATION:info};self.sha=info['sha256']
|
||||
self.ledger=L.Ledger(self.root,self.sha,self.initial,1<<20,0)
|
||||
|
||||
def job(self,name):
|
||||
job=self.root/'jobs'/(name+'.json');put(job,{'entry_id':name})
|
||||
self.ledger.begin(name,job,{'synthetic':True})
|
||||
return job
|
||||
|
||||
def completion(self,name,job,*,payload=b'output',changes=None):
|
||||
out=self.root/'runs'/name/'payload.dat';put(out,payload)
|
||||
process=self.root/'receipts'/(name+'.json')
|
||||
value=dict(entry_id=name,registration_sha256=self.sha,job_sha256=L.digest(job),complete=True,
|
||||
exit_code=0,timed_out=False,exit_observed_by_parent=True)
|
||||
value.update(changes or {});put(process,value)
|
||||
inputs={str(self.reg):L.identity(self.reg),str(job):L.identity(job)}
|
||||
outputs={str(p):L.identity(p) for p in (job,out,process)}
|
||||
metadata=dict(job_file=str(job),process_receipt_file=str(process),scope='synthetic completed parent job only',observed_returncode=0)
|
||||
return inputs,outputs,metadata
|
||||
|
||||
def commit(self,name):
|
||||
job=self.job(name);args=self.completion(name,job)
|
||||
return self.ledger.append(name,*args)
|
||||
|
||||
def test_two_entries_chain_full_tree_and_cumulative_bytes(self):
|
||||
one=self.commit('one');two=self.commit('two')
|
||||
second=L.read_json(self.root/L.CONTROL/'entries/0000000000000002.json')
|
||||
self.assertEqual(second['prev_entry_sha256'],one['entry_sha256'])
|
||||
self.assertEqual(two['entry_sha256'],L.digest(self.root/L.CONTROL/'entries/0000000000000002.json'))
|
||||
inspected=self.ledger.inspect();self.assertEqual(inspected['entry_ids'],['one','two'])
|
||||
self.assertFalse(inspected['retry_authorized']);self.assertTrue(inspected['all_tracked_history_rehashed'])
|
||||
final=self.ledger.final_verify(['one','two']);self.assertTrue(final['pass_all'])
|
||||
self.assertEqual(final['actual_total_bytes'],sum(p.stat().st_size for p in self.root.rglob('*') if p.is_file()))
|
||||
self.assertFalse(final['scientific_gate_claimed'])
|
||||
|
||||
def test_reopen_independent_read_verifies_no_reexecution_or_duplicate_append(self):
|
||||
self.commit('one')
|
||||
reopened=L.Ledger(self.root,self.sha,self.initial,1<<20,0)
|
||||
self.assertEqual(reopened.inspect()['entry_ids'],['one'])
|
||||
with self.assertRaisesRegex(ValueError,'already started/committed'):
|
||||
reopened.begin('one',self.root/'jobs/one.json')
|
||||
with self.assertRaisesRegex(ValueError,'No unique uncommitted'):
|
||||
reopened.append('one',{}, {},dict(job_file='x',process_receipt_file='y',scope='s',observed_returncode=0))
|
||||
|
||||
def test_pending_or_live_handle_is_unknown_and_never_retry_authority(self):
|
||||
job=self.job('live');state=self.ledger.inspect()
|
||||
self.assertEqual(state['uncommitted_state'],'STARTED-UNCOMMITTED-STATE-UNKNOWN')
|
||||
self.assertFalse(state['retry_authorized'])
|
||||
with self.assertRaisesRegex(ValueError,'uncommitted start'):self.ledger.begin('another',job)
|
||||
args=list(self.completion('live',job));args[2]['observed_returncode']=None
|
||||
with self.assertRaisesRegex(ValueError,'Live/failed'):self.ledger.append('live',*args)
|
||||
final=self.ledger.final_verify(['live']);self.assertFalse(final['pass_all']);self.assertTrue(final['uncommitted_state_unknown'])
|
||||
reopened=L.Ledger(self.root,self.sha,self.initial,1<<20,0)
|
||||
self.assertEqual(reopened.inspect()['uncommitted_entry_ids'],['live'])
|
||||
|
||||
def test_actual_parent_receipt_required_not_worker_success_or_bool_exit(self):
|
||||
job=self.job('one')
|
||||
for mutation in ({'exit_code':False},{'complete':False},{'exit_observed_by_parent':False},
|
||||
{'timed_out':True},{'registration_sha256':'0'*64},{'job_sha256':'0'*64},{'entry_id':'other'}):
|
||||
args=self.completion('one',job,changes=mutation)
|
||||
with self.subTest(mutation=mutation),self.assertRaisesRegex(ValueError,'parent process receipt'):
|
||||
self.ledger.append('one',*args)
|
||||
|
||||
def test_same_size_same_mtime_mutation_fails_actual_SHA(self):
|
||||
job=self.job('one');args=self.completion('one',job,payload=b'aaaa')
|
||||
out=self.root/'runs/one/payload.dat';stat=out.stat();out.write_bytes(b'bbbb')
|
||||
os.utime(out,ns=(stat.st_atime_ns,stat.st_mtime_ns))
|
||||
with self.assertRaisesRegex(ValueError,'Actual file SHA/bytes'):self.ledger.append('one',*args)
|
||||
|
||||
def test_missing_extra_changed_files_reported_at_full_audit(self):
|
||||
self.commit('one');out=self.root/'runs/one/payload.dat'
|
||||
extra=self.root/'unexpected.log';put(extra,b'extra')
|
||||
final=self.ledger.final_verify(['one']);self.assertFalse(final['pass_all']);self.assertIn('unexpected.log',final['extra_files'])
|
||||
out.unlink();final=self.ledger.final_verify(['one'])
|
||||
self.assertIn('runs/one/payload.dat',final['missing_files'])
|
||||
put(out,b'different');final=self.ledger.final_verify(['one'])
|
||||
self.assertIn('runs/one/payload.dat',final['changed_files'])
|
||||
|
||||
def test_tail_and_middle_tamper_not_trusted_by_inspect(self):
|
||||
self.commit('one');self.commit('two')
|
||||
first=self.root/L.CONTROL/'entries/0000000000000001.json'
|
||||
value=L.read_json(first);value['metadata']['scope']='tampered'
|
||||
put(first,value)
|
||||
with self.assertRaisesRegex(ValueError,'chain/start identity'):self.ledger.inspect()
|
||||
self.assertFalse(self.ledger.final_verify(['one','two'])['pass_all'])
|
||||
|
||||
def test_previously_observed_head_rewrite_rejected_even_new_valid_JSON(self):
|
||||
self.commit('one');path=self.root/L.CONTROL/'entries/0000000000000001.json'
|
||||
value=L.read_json(path);value['metadata']['scope']='changed';put(path,value)
|
||||
with self.assertRaisesRegex(ValueError,'head changed'):self.ledger.inspect()
|
||||
|
||||
def test_registered_final_entry_order_and_coverage_are_exact(self):
|
||||
self.commit('one');self.commit('two')
|
||||
for expected in (['two','one'],['one'],['one','two','three']):
|
||||
report=self.ledger.final_verify(expected)
|
||||
self.assertFalse(report['pass_all']);self.assertFalse(report['expected_order_exact'])
|
||||
with self.assertRaisesRegex(ValueError,'expected entry order'):self.ledger.final_verify(['one','one'])
|
||||
|
||||
def test_path_escape_aliases_and_overwrite_rejected(self):
|
||||
self.commit('one');job=self.job('two');inputs,outputs,meta=self.completion('two',job)
|
||||
outside=self.root.parent/'outside.dat';put(outside,b'external')
|
||||
outputs[str(outside)]=L.identity(outside)
|
||||
with self.assertRaisesRegex(ValueError,'escapes experiment'):self.ledger.append('two',inputs,outputs,meta)
|
||||
del outputs[str(outside)];old=self.root/'runs/one/payload.dat';outputs[str(old)]=L.identity(old)
|
||||
with self.assertRaisesRegex(ValueError,'previously tracked'):self.ledger.append('two',inputs,outputs,meta)
|
||||
del outputs[str(old)];outputs['runs/two/payload.dat']=outputs[str(self.root/'runs/two/payload.dat')]
|
||||
with self.assertRaisesRegex(ValueError,'Duplicate path aliases'):self.ledger.append('two',inputs,outputs,meta)
|
||||
with self.assertRaisesRegex(ValueError,'Escaping/noncanonical'):L.relative_name('../escape')
|
||||
|
||||
def test_consumed_tracked_input_cannot_be_silently_reauthorized_with_new_SHA(self):
|
||||
self.commit('one');job=self.job('two');inputs,outputs,meta=self.completion('two',job)
|
||||
prior=self.root/'runs/one/payload.dat';put(prior,b'overwritten')
|
||||
inputs[str(prior)]=L.identity(prior)
|
||||
with self.assertRaisesRegex(ValueError,'committed identity'):self.ledger.append('two',inputs,outputs,meta)
|
||||
|
||||
def test_external_inputs_allowed_but_declared_bytes_reverified(self):
|
||||
job=self.job('one');inputs,outputs,meta=self.completion('one',job)
|
||||
external=self.root.parent/'frozen-reference.json';put(external,{'read_only':'data'})
|
||||
inputs[str(external)]=L.identity(external);self.ledger.append('one',inputs,outputs,meta)
|
||||
row=L.read_json(self.root/L.CONTROL/'entries/0000000000000001.json')
|
||||
self.assertIsNone(next(r for r in row['consumed_inputs'] if r['path']==str(external))['relative_path'])
|
||||
put(external,{'read_only':'changed'})
|
||||
with self.assertRaisesRegex(ValueError,'Actual file SHA/bytes'):self.ledger.inspect()
|
||||
|
||||
def test_full_audit_hashes_shared_external_input_once_per_invocation(self):
|
||||
external=self.root.parent/'large-shared-reference';put(external,b'fixed external bytes')
|
||||
expected=L.identity(external)
|
||||
for name in ('one','two','three'):
|
||||
job=self.job(name);inputs,outputs,meta=self.completion(name,job)
|
||||
inputs[str(external)]=expected;self.ledger.append(name,inputs,outputs,meta)
|
||||
original=L.digest;counts={}
|
||||
def counted(path):
|
||||
key=str(Path(path));counts[key]=counts.get(key,0)+1
|
||||
return original(path)
|
||||
with patch.object(L,'digest',side_effect=counted):
|
||||
self.assertTrue(self.ledger.final_verify(['one','two','three'])['pass_all'])
|
||||
self.assertEqual(counts[str(external)],1)
|
||||
counts.clear();self.ledger.inspect();self.assertEqual(counts[str(external)],1)
|
||||
counts.clear();self.ledger.inspect();self.assertEqual(counts[str(external)],1)
|
||||
oldstat=external.stat();external.write_bytes(b'other external bytes')
|
||||
os.utime(external,ns=(oldstat.st_atime_ns,oldstat.st_mtime_ns))
|
||||
with self.assertRaisesRegex(ValueError,'Actual file SHA/bytes'):self.ledger.inspect()
|
||||
|
||||
def test_append_does_not_iterate_or_sum_historical_maps_or_search_ordered_ids(self):
|
||||
self.commit('one')
|
||||
class LookupOnlyDict(dict):
|
||||
def __iter__(self):raise AssertionError('Historical map iteration in fast append')
|
||||
def keys(self):raise AssertionError('Historical map copy in fast append')
|
||||
def values(self):raise AssertionError('Historical map sum in fast append')
|
||||
def items(self):raise AssertionError('Historical map iteration in fast append')
|
||||
class NoLinearMembership(list):
|
||||
def __contains__(self,value):raise AssertionError('Linear completed-ID membership')
|
||||
self.ledger._tracked=LookupOnlyDict(self.ledger._tracked)
|
||||
self.ledger._controls=LookupOnlyDict(self.ledger._controls)
|
||||
self.ledger._completed=NoLinearMembership(self.ledger._completed)
|
||||
self.commit('two')
|
||||
self.assertEqual(self.ledger._completed,['one','two'])
|
||||
self.assertTrue(self.ledger.final_verify(['one','two'])['pass_all'])
|
||||
|
||||
def test_head_is_freshly_checked_after_cached_full_tree_walk(self):
|
||||
self.commit('one');tail=self.root/L.CONTROL/'entries/0000000000000001.json'
|
||||
original_replay=self.ledger._replay;original_identity=self.ledger._identity_once
|
||||
state={'walking':False,'mutated':False}
|
||||
def replay(verified):
|
||||
original_replay(verified);state['walking']=True
|
||||
def during_walk(path,verified):
|
||||
if state['walking'] and not state['mutated']:
|
||||
value=L.read_json(tail);value['metadata']['scope']='mutation during final walk'
|
||||
put(tail,value);state['mutated']=True
|
||||
return original_identity(path,verified)
|
||||
with patch.object(self.ledger,'_replay',side_effect=replay),\
|
||||
patch.object(self.ledger,'_identity_once',side_effect=during_walk):
|
||||
report=self.ledger.final_verify(['one'])
|
||||
self.assertTrue(state['mutated']);self.assertFalse(report['pass_all'])
|
||||
self.assertTrue(any('Known ledger tail changed' in message for message in report['errors']))
|
||||
|
||||
def test_shared_mutable_build_separate_current_inventory_and_cap(self):
|
||||
build=self.root/'extension-build/cache.bin';put(build,b'first');self.commit('one')
|
||||
put(build,b'changed build is allowed');self.commit('two')
|
||||
report=self.ledger.final_verify(['one','two']);self.assertTrue(report['pass_all'])
|
||||
self.assertEqual(report['shared_mutable_build_bytes'],len(b'changed build is allowed'))
|
||||
self.assertNotIn('extension-build/cache.bin',report['extra_files'])
|
||||
put(build,b'x'*(1<<20));report=self.ledger.final_verify(['one','two'])
|
||||
self.assertFalse(report['pass_all']);self.assertFalse(report['output_cap_respected'])
|
||||
|
||||
def test_stale_writer_lock_and_partial_publication_never_auto_cleared(self):
|
||||
lock=self.root/L.CONTROL/'writer.lock';put(lock,b'unknown owner')
|
||||
with self.assertRaises(FileExistsError):self.ledger.begin('one',self.reg)
|
||||
with self.assertRaisesRegex(ValueError,'state unknown'):self.ledger.inspect()
|
||||
self.assertEqual(lock.read_bytes(),b'unknown owner')
|
||||
|
||||
def test_exclusive_atomic_publication_and_preserved_failed_temporary(self):
|
||||
target=self.root/'standalone.json';info=L.publish_exclusive(target,{'a':1})
|
||||
self.assertEqual(info,L.identity(target))
|
||||
with self.assertRaisesRegex(ValueError,'already exists'):L.publish_exclusive(target,{'a':2})
|
||||
self.assertEqual(L.read_json(target),{'a':1})
|
||||
target2=self.root/'failed.json'
|
||||
with patch.object(L.os,'link',side_effect=OSError('synthetic unsupported filesystem')):
|
||||
with self.assertRaises(OSError):L.publish_exclusive(target2,{'a':2})
|
||||
self.assertFalse(target2.exists());self.assertEqual(len(list(self.root.glob('.publishing-*'))),1)
|
||||
|
||||
def test_linked_output_rejected_if_platform_supports_links(self):
|
||||
source=self.root.parent/'other';source.mkdir();link=self.root/'linked'
|
||||
try:link.symlink_to(source,target_is_directory=True)
|
||||
except OSError:self.skipTest('Platform disallows synthetic symlink')
|
||||
job=self.job('one');inputs,outputs,meta=self.completion('one',job)
|
||||
put(source/'payload',b'x');outputs[str(link/'payload')]=L.identity(source/'payload')
|
||||
with self.assertRaisesRegex(ValueError,'Linked'):self.ledger.append('one',inputs,outputs,meta)
|
||||
|
||||
def test_initial_and_header_authority_are_not_optional(self):
|
||||
for change in ('registration','options'):
|
||||
with self.subTest(change=change),self.assertRaises(ValueError):
|
||||
L.Ledger(self.root,'0'*64 if change=='registration' else self.sha,self.initial,
|
||||
2<<20 if change=='options' else 1<<20,0)
|
||||
header=self.root/L.CONTROL/'header.json';value=L.read_json(header);value['max_output_bytes']+=1;put(header,value)
|
||||
with self.assertRaisesRegex(ValueError,'header changed'):self.ledger.inspect()
|
||||
|
||||
|
||||
if __name__=='__main__':unittest.main()
|
||||
@@ -0,0 +1,73 @@
|
||||
"""CPU request descriptors and pinned static transform, never a CUDA test."""
|
||||
import copy
|
||||
import unittest
|
||||
import numpy as np
|
||||
import normal_inputs as I
|
||||
from normal_io import load_source, LAB
|
||||
from normal_runner import compose_requests, derive_spec
|
||||
|
||||
class InputsTest(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.inputs=load_source('_normal_test_CI', LAB/'conditioning_inputs.py',I.PINS['conditioning_inputs.py'])
|
||||
|
||||
def task(self,arm='paired',cs=True):
|
||||
return dict(task_id='block/normal/'+arm+'/000',kind='train',arm=arm,steps=1200,mode='physiological',
|
||||
recipe=dict(cs=None if not cs else dict(cue='A',seed=2**62+37,start_tick=0,stop_tick_exclusive=1000,source_stream_id='s'),
|
||||
us=dict(nominal_slot_tick=900,rng_seed=None,rng_draws=0,requested=True,tick=900),
|
||||
D_command=0. if arm=='d_zero' else 1.,update_enabled=arm!='frozen'))
|
||||
|
||||
def test_full63_seed_and_aliases(self):
|
||||
a=self.task();b=self.task('d_zero')
|
||||
self.assertEqual(I.descriptor(a),I.descriptor(b))
|
||||
self.assertEqual(I.descriptor(a)['seed'],2**62+37)
|
||||
|
||||
def test_empty_CS_is_not_resampled(self):
|
||||
self.assertIsNone(I.descriptor(self.task('dan_only',False)))
|
||||
|
||||
def test_all_DAN_ids_and_counterfactual_US(self):
|
||||
dan=np.array([10,20],np.int32);empty=dict(tick=np.empty(0,np.int32),neuron_idx=np.empty(0,np.int32))
|
||||
for arm in ('paired','d_zero','frozen'):
|
||||
composed,us=compose_requests(empty,dan,self.task(arm),self.inputs)
|
||||
np.testing.assert_array_equal(composed['requests']['neuron_idx'],dan)
|
||||
self.assertEqual(us['tick'].tolist(),[900,900])
|
||||
|
||||
def test_no_US_and_zero_command(self):
|
||||
task=self.task('cs_only');task['recipe']['us'].update(requested=False,tick=None);task['recipe']['D_command']=0.
|
||||
cs=dict(tick=np.array([1],np.int32),neuron_idx=np.array([5],np.int32))
|
||||
combined,us=compose_requests(cs,np.array([10,20],np.int32),task,self.inputs)
|
||||
self.assertEqual(len(us['tick']),0);self.assertEqual(combined['requests']['neuron_idx'].tolist(),[5])
|
||||
|
||||
def test_conflict_and_command_fail_closed(self):
|
||||
cs=dict(tick=np.array([900],np.int32),neuron_idx=np.array([10],np.int32))
|
||||
with self.assertRaises(ValueError):compose_requests(cs,np.array([10,20],np.int32),self.task(),self.inputs)
|
||||
task=self.task('d_zero');task['recipe']['D_command']=1.
|
||||
with self.assertRaises(ValueError):compose_requests(cs,np.array([10,20],np.int32),task,self.inputs)
|
||||
|
||||
def test_probe_no_US_no_update(self):
|
||||
p=dict(kind='probe',mode='matched_energy',steps=1200,feedback_to_training_or_idle=False,
|
||||
recipe=dict(cue='B',input=dict(seed=2**61,stream_id='eval'),cs_start_tick=0,cs_stop_tick_exclusive=1000,
|
||||
US_requested=False,D_command=0.,weight_updates_enabled=False))
|
||||
d=I.descriptor(p);self.assertEqual(d['table_id'],'matched_energy--B')
|
||||
empty=dict(tick=np.empty(0,np.int32),neuron_idx=np.empty(0,np.int32))
|
||||
combined,us=compose_requests(empty,np.array([10,20],np.int32),p,self.inputs)
|
||||
self.assertEqual(len(combined['requests']['tick']),0)
|
||||
p['feedback_to_training_or_idle']=True
|
||||
with self.assertRaises(ValueError):compose_requests(empty,np.array([10,20],np.int32),p,self.inputs)
|
||||
|
||||
def test_clock_rejected(self):
|
||||
task=self.task();task['steps']=1800
|
||||
with self.assertRaises(ValueError):I.descriptor(task)
|
||||
|
||||
def test_case_math_config_retained(self):
|
||||
original=dict(kind='fullgraph',dt_ms=.1,apl_delay_steps=18,precision='float64',apl_precision='float32',
|
||||
record_history=False,seed=1073741825,model=dict(tau=20),apl=dict(gain=.01),graph_dir='/frozen/graph',
|
||||
rate_sum_hz=1,mode='physiological')
|
||||
task=self.task();task['mode']='matched_energy';before=copy.deepcopy(original)
|
||||
spec=derive_spec(original,task,budget_root='/new/exp',output_cap=1234)
|
||||
self.assertEqual(original,before)
|
||||
for key in ('dt_ms','apl_delay_steps','precision','apl_precision','seed','model','apl','graph_dir'):
|
||||
self.assertEqual(spec[key],original[key])
|
||||
self.assertEqual(spec['steps'],1200);self.assertFalse(spec['within_trial_weight_updates'])
|
||||
|
||||
if __name__=='__main__':unittest.main()
|
||||
@@ -0,0 +1,274 @@
|
||||
"""CPU arrays and mocked artifact I/O; these are not scientific observations."""
|
||||
import copy
|
||||
import hashlib
|
||||
import importlib.util
|
||||
import io
|
||||
from pathlib import Path
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
import numpy as np
|
||||
|
||||
spec = importlib.util.spec_from_file_location('_test_normal_metrics', Path(__file__).with_name('normal_metrics.py'))
|
||||
N = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(N)
|
||||
|
||||
|
||||
def fixture():
|
||||
nodes = np.arange(6, dtype=np.int32)
|
||||
pops = {k: np.asarray(v, np.int32) for k, v in dict(MBON=[0, 1], MBON01=[0], MBON12=[1],
|
||||
legacyDownstream=[0, 1, 2, 3], nonMBONDownstream=[2, 3]).items()}
|
||||
blocks, probes, arms = {}, {}, {}
|
||||
seed = 1
|
||||
for mode in N.M.MODES:
|
||||
for dan in N.M.DAN_TYPES:
|
||||
for cue in ('A', 'B'):
|
||||
for rep in range(1, 6):
|
||||
identity = f'{mode}__{dan}__reinforce_{cue}__rep{rep:02d}'
|
||||
sources = []
|
||||
for split in ('training', 'design'):
|
||||
sources.append(dict(stream_id=identity + '/' + split, seed=seed, split=split)); seed += 1
|
||||
evaluation = {}
|
||||
for c in ('A', 'B'):
|
||||
evaluation[N.ODORS[c]] = dict(stream_id=identity + '/evaluation/' + c, seed=seed, split='evaluation'); seed += 1
|
||||
blocks[identity] = dict(mode=mode, dan_type=dan, compartment_verbatim=N.G.DAN_COMPARTMENTS[dan],
|
||||
conditioned_cue=N.ODORS[cue], replicate=rep, training_sources=sources, evaluation_sources=evaluation,
|
||||
evaluation_input_sha256={N.ODORS[c]: N.sha([identity, c]) for c in ('A', 'B')})
|
||||
for arm in N.ARM_NAMES:
|
||||
arms[(identity, arm)] = [dict(result=[identity, arm, e], requested=e < 50 and arm != 'cs_only')
|
||||
for e in range(150 if arm == 'unpaired' else 100)]
|
||||
for point in N.POINTS:
|
||||
for c in ('A', 'B'):
|
||||
probes[(identity, arm, point, c)] = dict(block=identity, arm=arm, point=point, cue=c,
|
||||
active=arm == 'paired' and point > 0 and c == cue and rep <= 3, dan=dan)
|
||||
membership = N.M.validate_populations(nodes, pops)
|
||||
registry = dict(schema=N.G.REGISTRY_SCHEMA, protocol_sha256='1' * 64, population_binding_sha256='2' * 64,
|
||||
nodes_raw_sha256=N.M._hash(nodes), population_membership_sha256=membership['membership_sha256'], blocks=blocks)
|
||||
authority = dict(schema=N.G.AUTHORITY_SCHEMA, registry_sha256=N.G.descriptor_sha256(registry),
|
||||
verification_receipt_sha256='3' * 64, execution_inventory_sha256='4' * 64, population_binding_sha256='2' * 64)
|
||||
return nodes, pops, registry, authority, probes, arms
|
||||
|
||||
|
||||
def state_for(record):
|
||||
ids = np.asarray(sorted([1 if record['dan'] == 'PAM15' else 0, 2]) if record['active'] else [], np.int32)
|
||||
state = dict(step=np.full(len(ids), 10, np.int32), neuron_idx=ids,
|
||||
counts=np.bincount(ids, minlength=6).astype(np.int32), v=np.zeros(6, np.float64),
|
||||
g=np.zeros(6, np.float64), ref=np.zeros(6, np.int32))
|
||||
if record['active']:
|
||||
state['g'][ids[0]] = .1
|
||||
return state
|
||||
|
||||
|
||||
class MockReader:
|
||||
def __init__(self, values):
|
||||
self.values = values
|
||||
self.inventory = {str(p): dict(bytes=len(N.canonical(v)), sha256=N.sha(v)) for p, v in values.items()}
|
||||
def json(self, path): return copy.deepcopy(self.values[str(path)])
|
||||
def check(self, path): return self.inventory[str(path)]
|
||||
def path(self, path): return Path(path), self.inventory[str(path)]
|
||||
|
||||
|
||||
def process_fixture():
|
||||
exp = Path.cwd() / 'mock-normal-evidence'
|
||||
entry_id = 'input-generation'; regsha = '1' * 64
|
||||
job_path = exp / 'jobs/input-generation.json'
|
||||
proc_path = exp / 'receipts/input-generation/process.json'
|
||||
start_path = exp / '.append-ledger/started/input-generation.json'
|
||||
entry_path = exp / '.append-ledger/entries/0000000000000001.json'
|
||||
values = {str(job_path): dict(kind='sample', registration_sha256=regsha, input_sha256={})}
|
||||
for label in ('stdout', 'stderr'):
|
||||
values[str(exp / f'logs/input-generation.{label}.log')] = {'log': label}
|
||||
values[str(proc_path)] = dict(entry_id=entry_id, registration_sha256=regsha, job_sha256=N.sha(values[str(job_path)]),
|
||||
complete=True, exit_code=0, timed_out=False, exit_observed_by_parent=True,
|
||||
stdout_sha256=N.sha({'log': 'stdout'}), stderr_sha256=N.sha({'log': 'stderr'}))
|
||||
r = MockReader(values)
|
||||
row = lambda p: dict(path=str(p), relative_path=Path(p).relative_to(exp).as_posix(), **r.inventory[str(p)])
|
||||
values[str(start_path)] = dict(entry_id=entry_id, registration_sha256=regsha, next_sequence=1,
|
||||
prev_entry_sha256=None, retry_authorized=False, job=row(job_path))
|
||||
values[str(entry_path)] = dict(entry_id=entry_id, registration_sha256=regsha, sequence=1,
|
||||
prev_entry_sha256=None, start_sha256=N.sha(values[str(start_path)]), consumed_inputs=[row(job_path)],
|
||||
new_outputs=[row(p) for p in list(values) if p != str(start_path)],
|
||||
metadata=dict(job_file=str(job_path), process_receipt_file=str(proc_path), observed_returncode=0))
|
||||
final = dict(schema='normal-append-ledger-v1-final-audit', registration_sha256=regsha, pass_all=True,
|
||||
entry_ids=[entry_id], expected_entry_ids=[entry_id], expected_order_exact=True,
|
||||
extra_files=[], missing_files=[], changed_files=[], unsafe_files=[], errors=[], uncommitted_entry_ids=[],
|
||||
uncommitted_state_unknown=False, head_sha256=N.sha(values[str(entry_path)]))
|
||||
return exp, values, final, proc_path, entry_path
|
||||
|
||||
|
||||
def case_fixture(no_cs=False):
|
||||
exp = Path.cwd() / 'mock-normal-case'; population_file = str(exp / 'population.npz')
|
||||
seed = (1 << 62) + 17
|
||||
task = dict(task_id='real-recipe/epoch-000', kind='train', mode='physiological', arm='dan_only' if no_cs else 'paired',
|
||||
dan_type='PAM15', recipe=dict(cs=None if no_cs else dict(cue='A', seed=seed, source_stream_id='independent-original'),
|
||||
us=dict(requested=True), D_command=1.0))
|
||||
case = exp / 'cases' / N.task_key(task)
|
||||
template = dict(kind='fullgraph', steps=1200, dt_ms=.1, apl_delay_steps=18, precision='float64',
|
||||
apl_precision='float32', record_history=False, seed=98765, synaptic_tau=5.0, cs_input_seed=999)
|
||||
spec = {k: v for k, v in template.items() if k != 'cs_input_seed'}
|
||||
spec.update(name=N.task_key(task), steps=1200, duration_ms=120., max_steps=1200, budget_root=str(exp),
|
||||
output_budget_bytes=123, mode=task['mode'], within_trial_weight_updates=False,
|
||||
outer_protocol='normal-acquisition-v1', outer_task_id=task['task_id'], outer_arm=task['arm'])
|
||||
descriptor = dict(mode=task['mode'], cue='A', seed=seed, steps=1200, cs_start_tick=0,
|
||||
cs_stop_tick_exclusive=1000, source_stream_id='independent-original', table_id='physiological--A')
|
||||
csid = None if no_cs else N.sha(descriptor)
|
||||
arrays = {}
|
||||
source = dict(tick=np.asarray([] if no_cs else [10], np.int32), neuron_idx=np.asarray([] if no_cs else [3], np.int32))
|
||||
dan = np.asarray([4, 5, 6, 7], np.int32)
|
||||
us = dict(tick=np.full(4, 900, np.int32), neuron_idx=dan)
|
||||
combined = {k: np.concatenate((source[k], us[k])) for k in source}
|
||||
for name, value in (('cs_requests.npz', source), ('us_requests.npz', us), ('requests.npz', combined),
|
||||
('source-mask.npz', dict(source_mask=np.asarray(([1] if not no_cs else []) + [2]*4, np.uint8)))):
|
||||
arrays[str(case / name)] = value
|
||||
values = {str(case / 'spec.json'): spec, population_file: {'artifact': 'actual-static-populations'}}
|
||||
source_pin = None; sampler = dict(inputs={})
|
||||
if not no_cs:
|
||||
source_path = exp / f'inputs/generated/{csid}.npz'; audit_path = exp / f'inputs/generated/{csid}.json'
|
||||
values[str(source_path)] = {'array-artifact': 'mock-sparse-CS'}
|
||||
arrays[str(source_path)] = source
|
||||
source_pin = dict(path=str(source_path), sha256=N.sha(values[str(source_path)]))
|
||||
values[str(audit_path)] = dict(descriptor=descriptor, requests_sha256=source_pin['sha256'], audit=dict(seed=seed,
|
||||
generator_initial_seed=seed, seed_bits=63, seed_conversion='exact integer; no truncation/modulo/offset',
|
||||
private_generator=True, matrix_draw_calls=1, uniform_matrix_shape=[1200, 1], CS_window=[0, 1000]))
|
||||
sampler['inputs'][csid] = dict(requests=source_pin, audit=dict(path=str(audit_path), sha256=N.sha(values[str(audit_path)])))
|
||||
values[str(case / 'input-binding.json')] = dict(task_id=task['task_id'], CS_descriptor_id=csid, CS_source=source_pin,
|
||||
DAN_type='PAM15', population_file=dict(path=population_file, sha256=N.sha(values[population_file])),
|
||||
DAN_membership_sha256=hashlib.sha256(dan.tobytes()).hexdigest(), composition=dict(policy='error', cross_source_conflict_count=0))
|
||||
reader = MockReader(values)
|
||||
reader.arrays = lambda p: {k: v.copy() for k, v in arrays[str(p)].items()}
|
||||
args = dict(template=template, inputs=dict(task_inputs={task['task_id']: csid}, descriptors={} if no_cs else {csid: descriptor}),
|
||||
sampler=sampler, populations=dict(PAM15=dan), population_file=population_file, output_cap=123)
|
||||
return reader, exp, task, dict(case_dir=str(case)), args, values, arrays, case
|
||||
|
||||
|
||||
class NormalMetricTests(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.nodes, cls.pops, cls.registry, cls.authority, cls.probes, cls.arms = fixture()
|
||||
cls.full_reports = {}
|
||||
original = N.G.evaluate_acquisition
|
||||
def capture(*args, **kwargs):
|
||||
result = original(*args, **kwargs)
|
||||
cls.full_reports[(result['mode'], result['dan_type'], result['conditioned_cue'])] = result
|
||||
return result
|
||||
with patch.object(N.G, 'evaluate_acquisition', side_effect=capture):
|
||||
cls.report = N.scientific_reports(cls.probes, cls.arms, registry=cls.registry, authority=cls.authority,
|
||||
nodes=cls.nodes, populations=cls.pops, load_state=state_for)
|
||||
|
||||
def test_full_fixed_curves_and_eight_same_replicate_gates(self):
|
||||
self.assertEqual(len(self.report['cells']), 8)
|
||||
self.assertEqual(len(self.report['curves']), 1960)
|
||||
self.assertTrue(self.report['cohort']['all_functional_predicates_pass'])
|
||||
self.assertTrue(all(r['successful_same_replicate_conjunctions'] == 3 for r in self.report['cells']))
|
||||
self.assertTrue(all('acquisition_metric_inputs' not in r for r in self.report['cells']))
|
||||
self.assertTrue(all(not r['scientific_learning_pass_claimed'] for r in self.report['cells']))
|
||||
self.assertEqual({r['checkpoint'] for r in self.report['curves']}, set(N.POINTS))
|
||||
self.assertTrue(all(r['metrics']['rawS'] == 0 for r in self.report['curves'] if r['checkpoint'] == 0))
|
||||
self.assertTrue(all(not isinstance(v, list) for r in self.report['curves']
|
||||
for cue in r['metrics']['cues'].values() for group in cue['populations'].values() for v in group.values()))
|
||||
|
||||
def test_legacy_mapping_exactly_matches_frozen_wrapper(self):
|
||||
expected = N.G.legacy_h_cohort_audit(list(self.full_reports.values()), registry=self.registry,
|
||||
authority=self.authority, declared_mapping=N.G.H_MAPPING)
|
||||
actual = N.legacy_audit(self.report['cells'], N.G.H_MAPPING)
|
||||
self.assertEqual(actual, expected)
|
||||
self.assertEqual(len(actual['groups']), 4)
|
||||
self.assertTrue(all(set(g['control_sources']) == {'PAM15', 'PPL103'} for g in actual['groups']))
|
||||
with self.assertRaises(ValueError): N.legacy_audit(self.report['cells'], None)
|
||||
|
||||
def test_training_evaluation_seed_collision_and_missing_control_fail_closed(self):
|
||||
registry = copy.deepcopy(self.registry)
|
||||
block = next(iter(registry['blocks'].values()))
|
||||
block['evaluation_sources'][N.M.CUES[0]]['seed'] = block['training_sources'][0]['seed']
|
||||
with self.assertRaisesRegex(ValueError, 'collision'):
|
||||
N.G.validate_registry(registry, expected_sha256=N.G.descriptor_sha256(registry))
|
||||
report = next(iter(self.full_reports.values()))
|
||||
rows = copy.deepcopy(report['acquisition_metric_inputs'])
|
||||
del rows[0]['arms']['DAN-only']
|
||||
with self.assertRaisesRegex(ValueError, 'six actual controls'):
|
||||
N.G.evaluate_acquisition(rows, assay='normal', mode=report['mode'], dan_type=report['dan_type'],
|
||||
conditioned_cue=report['conditioned_cue'], registry=self.registry, authority=self.authority)
|
||||
|
||||
def test_state_mutation_and_absent_probe_never_become_zero_metrics(self):
|
||||
probes = dict(self.probes); del probes[next(iter(probes))]
|
||||
with self.assertRaises((KeyError, ValueError)):
|
||||
N.scientific_reports(probes, self.arms, registry=self.registry, authority=self.authority,
|
||||
nodes=self.nodes, populations=self.pops, load_state=state_for)
|
||||
def corrupt(record):
|
||||
state = state_for(record); state['g'][0] = np.nan; return state
|
||||
with self.assertRaisesRegex(ValueError, 'Nonfinite'):
|
||||
N.scientific_reports(self.probes, self.arms, registry=self.registry, authority=self.authority,
|
||||
nodes=self.nodes, populations=self.pops, load_state=corrupt)
|
||||
|
||||
def test_actual_parent_receipt_nested_layout_and_exit_failure(self):
|
||||
exp, values, final, proc, _ = process_fixture()
|
||||
evidence = N.Evidence(MockReader(values), exp, '1' * 64, ['input-generation'], final)
|
||||
observed = evidence.process('input-generation', 'sample'); evidence.finish()
|
||||
self.assertEqual(observed['process_path'], str(exp / 'receipts/input-generation/process.json'))
|
||||
values[str(proc)]['exit_code'] = 1
|
||||
# Even a caller report saying pass_all cannot rescue a real exit failure.
|
||||
r = MockReader(values)
|
||||
entry = next(v for v in values.values() if 'new_outputs' in v)
|
||||
for row in entry['new_outputs']:
|
||||
if row['path'] == str(proc): row.update(r.inventory[str(proc)])
|
||||
with self.assertRaisesRegex(ValueError, 'Actual parent exit'):
|
||||
N.Evidence(MockReader(values), exp, '1' * 64, ['input-generation'], final).process('input-generation', 'sample')
|
||||
|
||||
def test_result_process_must_be_ledger_owned_not_only_metadata(self):
|
||||
exp, values, final, proc, entry_path = process_fixture()
|
||||
entry = values[str(entry_path)]
|
||||
entry['new_outputs'] = [r for r in entry['new_outputs'] if r['path'] != str(proc)]
|
||||
with self.assertRaisesRegex(ValueError, 'not owned'):
|
||||
N.Evidence(MockReader(values), exp, '1' * 64, ['input-generation'], final).process('input-generation', 'sample')
|
||||
bad = dict(final, uncommitted_entry_ids=['unknown-child'])
|
||||
with self.assertRaisesRegex(ValueError, 'Incomplete'):
|
||||
N.Evidence(MockReader(values), exp, '1' * 64, ['input-generation'], bad)
|
||||
|
||||
def test_reader_per_invocation_actual_sha_cache_and_no_boolean_substitution(self):
|
||||
path = Path.cwd() / 'mock-artifact.json'; raw = b'{"actual":true}'
|
||||
identity = dict(bytes=len(raw), sha256=hashlib.sha256(raw).hexdigest())
|
||||
with patch.object(Path, 'is_symlink', return_value=False), patch.object(Path, 'is_junction', return_value=False, create=True), \
|
||||
patch.object(Path, 'is_file', return_value=True), patch.object(Path, 'open', side_effect=lambda *a, **k: io.BytesIO(raw)) as opened:
|
||||
reader = N.Reader({str(path): identity})
|
||||
reader.check(path); reader.check(path)
|
||||
self.assertEqual(opened.call_count, 1)
|
||||
N.Reader({str(path): identity}).check(path)
|
||||
self.assertEqual(opened.call_count, 2)
|
||||
with self.assertRaisesRegex(ValueError, 'Actual file checksum'):
|
||||
N.Reader({str(path): dict(bytes=len(raw), sha256='0' * 64)}).check(path)
|
||||
|
||||
def test_real_inventory_process_count_and_no_followup(self):
|
||||
tasks = [dict(task_id='train-' + str(i), kind='train') for i in range(30000)]
|
||||
tasks += [dict(task_id='probe-' + str(i), kind='probe') for i in range(3920)]
|
||||
entries = N.expected_entries(dict(tasks=tasks))
|
||||
self.assertEqual(len(entries), 93921)
|
||||
self.assertEqual(len(set(entries)), 93921)
|
||||
self.assertEqual(entries[0], 'input-generation')
|
||||
self.assertTrue(entries[-1].endswith('--brain'))
|
||||
|
||||
def test_original_train_cs_us_seed_and_model_checked_independently(self):
|
||||
reader, exp, task, job, args, values, arrays, case = case_fixture()
|
||||
N.audit_case(reader, exp, task, job, **args)
|
||||
arrays[str(case / 'us_requests.npz')]['tick'][0] = 901
|
||||
with self.assertRaisesRegex(ValueError, 'sorted unique|scheduled US'):
|
||||
N.audit_case(reader, exp, task, job, **args)
|
||||
arrays[str(case / 'us_requests.npz')]['tick'][0] = 900
|
||||
values[str(case / 'spec.json')]['seed'] += 1
|
||||
with self.assertRaisesRegex(ValueError, 'model/reset/clock'):
|
||||
N.audit_case(reader, exp, task, job, **args)
|
||||
values[str(case / 'spec.json')]['seed'] -= 1
|
||||
generated = next(v for v in values.values() if 'audit' in v)
|
||||
generated['audit']['generator_initial_seed'] %= 2**32
|
||||
with self.assertRaisesRegex(ValueError, 'sampler seed'):
|
||||
N.audit_case(reader, exp, task, job, **args)
|
||||
|
||||
def test_no_cs_is_empty_and_dan_only_still_uses_original_fixed_us(self):
|
||||
reader, exp, task, job, args, values, arrays, case = case_fixture(no_cs=True)
|
||||
N.audit_case(reader, exp, task, job, **args)
|
||||
arrays[str(case / 'cs_requests.npz')] = dict(tick=np.asarray([10], np.int32), neuron_idx=np.asarray([3], np.int32))
|
||||
with self.assertRaisesRegex(ValueError, 'case CS'):
|
||||
N.audit_case(reader, exp, task, job, **args)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -0,0 +1,160 @@
|
||||
"""CPU-only fixed inventory, authority, and dependency regression tests."""
|
||||
from collections import Counter, defaultdict
|
||||
import importlib.util
|
||||
from pathlib import Path
|
||||
import random
|
||||
import sys
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
|
||||
_SPEC = importlib.util.spec_from_file_location("normal_plan_test_subject", Path(__file__).with_name("normal_plan.py"))
|
||||
P = importlib.util.module_from_spec(_SPEC)
|
||||
_SPEC.loader.exec_module(P)
|
||||
|
||||
|
||||
class NormalPlanTests(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
# Deterministic recipe construction, NOT neural random sampling.
|
||||
cls.trial = P._FROZEN["trial_plan"].build_trial_plan(P.MASTER)
|
||||
cls.evaluation = P.expand_pinned_evaluation(cls.trial)
|
||||
with patch.object(random, "random", side_effect=AssertionError("RNG draw")), \
|
||||
patch.object(random, "Random", side_effect=AssertionError("RNG instance")):
|
||||
cls.plan = P.build_normal_plan(cls.trial, cls.evaluation)
|
||||
|
||||
def test_complete_inventory_and_order(self):
|
||||
plan = self.plan
|
||||
self.assertEqual(Counter(t["kind"] for t in plan["tasks"]), {"train": 30000, "probe": 3920})
|
||||
self.assertEqual(sum(t["steps"] for t in plan["tasks"]), 40704000)
|
||||
self.assertEqual(len(plan["blocks"]), 40)
|
||||
self.assertEqual(Counter((b["mode"], b["dan_type"], b["reinforced_cue"]) for b in plan["blocks"]),
|
||||
{(m, d, c): 5 for m in ("physiological", "matched_energy")
|
||||
for d in ("PAM15", "PPL103") for c in ("A", "B")})
|
||||
groups = defaultdict(list)
|
||||
for row in plan["tasks"]:
|
||||
groups[(row["block_id"], row["arm"])].append(row)
|
||||
self.assertEqual(list(groups), [(b["block_id"], a) for b in self.trial["plan"]["blocks"]
|
||||
for a in P._FROZEN["trial_plan"].ARMS])
|
||||
for (_, arm), rows in groups.items():
|
||||
self.assertEqual([r["kind"] for r in rows[:3]], ["probe", "probe", "train"])
|
||||
self.assertEqual([r["recipe"]["cue"] for r in rows[:2]], ["A", "B"])
|
||||
self.assertEqual(len(rows), 164 if arm == "unpaired" else 114)
|
||||
self.assertEqual([r["checkpoint"] for r in rows if r["kind"] == "probe"],
|
||||
[n for n in (0, 1, 2, 5, 10, 20, 50) for _ in range(2)])
|
||||
self.assertEqual(len(groups), 280)
|
||||
|
||||
def test_every_dependency_is_earlier_same_arm_delta_and_probes_do_not_feed_back(self):
|
||||
previous, completed = {}, Counter()
|
||||
for row in self.plan["tasks"]:
|
||||
key = row["block_id"], row["arm"]
|
||||
expected = previous.get(key, {"kind": "zero", "source": None})
|
||||
self.assertEqual(row["delta_dependency"], expected)
|
||||
self.assertTrue(row["artifact_validation_required"])
|
||||
if row["kind"] == "train":
|
||||
self.assertEqual(row["epoch_index"], completed[key])
|
||||
completed[key] += 1
|
||||
self.assertEqual(row["carry_between_epochs"], ["plastic_delta_only"])
|
||||
self.assertEqual(row["neural_state_policy"], "frozen_reset_including_KC_trace_and_both_delay_queues")
|
||||
self.assertTrue(row["original_E_required"] and row["cpu_validation_required"])
|
||||
previous[key] = {"kind": "epoch_delta_after", "source": row["delta_output_id"]}
|
||||
else:
|
||||
self.assertEqual(row["completed_epochs"], completed[key])
|
||||
self.assertEqual(row["snapshot_binding"]["completed_epochs"], completed[key])
|
||||
self.assertFalse(row["feedback_to_training_or_idle"])
|
||||
self.assertFalse(row["original_E_required"] or row["cpu_validation_required"])
|
||||
self.assertFalse(row["recipe"]["US_requested"] or row["recipe"]["weight_updates_enabled"])
|
||||
self.assertEqual(row["recipe"]["D_command"], 0.0)
|
||||
self.assertIsNone(row["delta_output_id"])
|
||||
|
||||
def test_frozen_control_recipes_not_nominal_boundaries(self):
|
||||
actual = {r["task_id"]: r for r in self.plan["tasks"]}
|
||||
for block in self.trial["plan"]["blocks"]:
|
||||
normal = next(s for s in block["suites"] if s["assay"] == "normal")
|
||||
for arm in normal["arms"]:
|
||||
for recipe in arm["epochs"]:
|
||||
row = actual[recipe["epoch_id"]]
|
||||
self.assertEqual(row["recipe"], recipe)
|
||||
self.assertEqual(row["source_binding"]["record_sha256"], P._sha(recipe))
|
||||
self.assertEqual(row["source_binding"]["payload_sha256"], self.trial["payload_sha256"])
|
||||
self.assertEqual(sum(e["us"]["requested"] for e in arm["epochs"]),
|
||||
0 if arm["arm"] == "cs_only" else 50)
|
||||
if arm["arm"] == "unpaired":
|
||||
self.assertTrue(all(not (e["cs"] and e["us"]["requested"]) for e in arm["epochs"]))
|
||||
for original in self.evaluation["probes"]:
|
||||
if original["assay"] == "normal":
|
||||
self.assertEqual(actual[original["probe_id"]]["recipe"], original)
|
||||
self.assertTrue(any(r["kind"] == "probe" and r["arm"] == "unpaired" and
|
||||
r["checkpoint"] == 50 and r["completed_epochs"] == 150
|
||||
for r in actual.values()))
|
||||
|
||||
def test_evaluation_inputs_reused_not_redrawn_or_counted_as_replicates(self):
|
||||
inputs = self.plan["evaluation_inputs"]
|
||||
self.assertEqual(len(inputs), 80)
|
||||
self.assertEqual(len({r["stream_id"] for r in inputs}), 80)
|
||||
seeds = {r["seed"] for r in inputs}
|
||||
training = {r["recipe"]["cs"]["seed"] for r in self.plan["tasks"]
|
||||
if r["kind"] == "train" and r["recipe"]["cs"] is not None}
|
||||
self.assertFalse(seeds & training)
|
||||
self.assertTrue(all(type(s) is int and 0 <= s < 2**63 for s in seeds | training))
|
||||
reuse = Counter(r["evaluation_input_id"] for r in self.plan["tasks"] if r["kind"] == "probe")
|
||||
self.assertEqual(set(reuse.values()), {49})
|
||||
self.assertEqual(set(reuse), {r["input_id"] for r in inputs})
|
||||
self.assertTrue(all(not r["recipe"]["adds_training_replicate"] for r in self.plan["tasks"] if r["kind"] == "probe"))
|
||||
self.assertEqual(self.plan["new_seed_streams"], 0)
|
||||
self.assertFalse(self.plan["learning_pass_claimed"] or self.plan["execution_authorized"])
|
||||
|
||||
def test_no_mutable_alias_to_authorities(self):
|
||||
row = next(r for r in self.plan["tasks"] if r["kind"] == "train")
|
||||
before = row["recipe"]["D_command"]
|
||||
try:
|
||||
row["recipe"]["D_command"] = 999
|
||||
original = self.trial["plan"]["blocks"][0]["suites"][0]["arms"][0]["epochs"][0]
|
||||
self.assertEqual(original["D_command"], before)
|
||||
finally:
|
||||
row["recipe"]["D_command"] = before
|
||||
self.assertIsNot(self.plan["provenance"]["frozen_source_sha256"], P.SOURCE_PINS)
|
||||
|
||||
def test_private_loader_ignores_ordinary_module_cache_and_fails_closed_on_source_pin(self):
|
||||
sentinels = {name: object() for name in ("seed_registry", "trial_plan", "evaluation_plan", "evaluation_policy", "R", "E")}
|
||||
with patch.dict(sys.modules, sentinels):
|
||||
loaded = P._load_frozen()
|
||||
self.assertIs(loaded["trial_plan"].seed_registry, loaded["seed_registry"])
|
||||
self.assertIs(loaded["evaluation_policy"].evaluation_plan, loaded["evaluation_plan"])
|
||||
self.assertTrue(all(sys.modules[name] is value for name, value in sentinels.items()))
|
||||
with patch.object(Path, "read_bytes", return_value=b"unregistered mutation"):
|
||||
with self.assertRaisesRegex(ValueError, "Frozen source pin mismatch"):
|
||||
P._load_frozen()
|
||||
|
||||
def test_original_trial_and_policy_mutation_rejected(self):
|
||||
master = self.trial["plan"]["master"]
|
||||
try:
|
||||
self.trial["plan"]["master"] = master + 1
|
||||
with self.assertRaisesRegex(ValueError, "master"):
|
||||
P.build_normal_plan(self.trial, self.evaluation)
|
||||
finally:
|
||||
self.trial["plan"]["master"] = master
|
||||
binding = self.evaluation["config"]["snapshot_bindings"][1]
|
||||
count = binding["completed_epochs"]
|
||||
try:
|
||||
binding["completed_epochs"] += 1
|
||||
with self.assertRaisesRegex(ValueError, "exactly expand"):
|
||||
P.build_normal_plan(self.trial, self.evaluation)
|
||||
finally:
|
||||
binding["completed_epochs"] = count
|
||||
|
||||
def test_validates_exact_reconstruction_and_rejects_rehashed_task_mutation(self):
|
||||
self.assertTrue(P.validate_normal_plan(self.plan, self.trial, self.evaluation))
|
||||
row, original_hash = self.plan["tasks"][0], self.plan["payload_sha256"]
|
||||
try:
|
||||
row["feedback_to_training_or_idle"] = True
|
||||
self.plan["payload_sha256"] = P._sha({k: v for k, v in self.plan.items() if k != "payload_sha256"})
|
||||
with self.assertRaisesRegex(ValueError, "exact reconstruction"):
|
||||
P.validate_normal_plan(self.plan, self.trial, self.evaluation)
|
||||
finally:
|
||||
row["feedback_to_training_or_idle"] = False
|
||||
self.plan["payload_sha256"] = original_hash
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,387 @@
|
||||
"""Pure temporary-file and mock-process tests; no sampler, Torch, brain or GPU."""
|
||||
import copy
|
||||
import importlib.util
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import tempfile
|
||||
import time
|
||||
from types import SimpleNamespace
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
import numpy as np
|
||||
import normal_runner as R
|
||||
import normal_prepare as P
|
||||
|
||||
|
||||
def load_readonly(name, path):
|
||||
spec=importlib.util.spec_from_file_location(name,path)
|
||||
module=importlib.util.module_from_spec(spec)
|
||||
exec(compile(path.read_bytes(),str(path),'exec'),module.__dict__)
|
||||
return module
|
||||
|
||||
|
||||
LAB=Path(__file__).resolve().parent.parent/'olfactory-conditioning-lab-v1'
|
||||
COMPOSER=load_readonly('_runner_test_original_composer',LAB/'conditioning_inputs.py')
|
||||
WORKER=load_readonly('_runner_test_original_worker',LAB.parent/'conditioning-interface-v2/isolated_workers.py')
|
||||
|
||||
|
||||
def task(arm='paired', *, requested=True, kind='train', dan='PAM15', number=1):
|
||||
value=dict(task_id=f'block/normal/{arm}/epoch-{number:03d}',kind=kind,steps=1200,
|
||||
block_id='block',arm=arm,mode='physiological',dan_type=dan,
|
||||
compartment_verbatim="y5B'2a" if dan=='PAM15' else "y2a'1",
|
||||
delta_dependency=dict(kind='zero',source=None),feedback_to_training_or_idle=kind=='train')
|
||||
if kind=='probe':
|
||||
value['recipe']=dict(US_requested=False,D_command=0,weight_updates_enabled=False)
|
||||
else:
|
||||
value['recipe']=dict(us=dict(nominal_slot_tick=900,rng_seed=None,rng_draws=0,
|
||||
requested=requested,tick=900 if requested else None),
|
||||
D_command=1. if requested and arm!='d_zero' else 0.,update_enabled=arm!='frozen')
|
||||
return value
|
||||
|
||||
|
||||
class RunnerTests(unittest.TestCase):
|
||||
def test_runtime_array_closure_matches_original_worker_not_directory_glob(self):
|
||||
self.assertEqual(P.GRAPH_FILES,WORKER.GRAPH_FILES)
|
||||
self.assertEqual(P.APL_FILES,WORKER.APL_FILES)
|
||||
with tempfile.TemporaryDirectory() as folder:
|
||||
root=Path(folder);graph=root/'graph';apl=root/'apl'
|
||||
graph.mkdir();apl.mkdir()
|
||||
# Additional reference arrays are neither consumed nor required.
|
||||
for name in ('apl_out_ids.npy','input_raw.npy','output_raw.npy','pn_globals.npy'):
|
||||
(apl/name).touch()
|
||||
template=dict(graph_dir=str(graph),apl_bundle_dir=str(apl),coefficients_path=str(root/'coeff.json'))
|
||||
paths=P.runtime_array_paths(template)
|
||||
expected={str(graph/name) for name in WORKER.GRAPH_FILES} | {
|
||||
str(apl/name) for name in WORKER.APL_FILES} | {template['coefficients_path']}
|
||||
self.assertEqual(paths,expected);self.assertEqual(len(paths),12)
|
||||
|
||||
def setUp(self):
|
||||
temporary=tempfile.TemporaryDirectory();self.addCleanup(temporary.cleanup)
|
||||
self.root=Path(temporary.name).resolve()
|
||||
for rel in ('protocol','jobs','cases','runs','updates','validation','results','receipts','logs','audit'):
|
||||
(self.root/rel).mkdir()
|
||||
self.addCleanup(patch.stopall)
|
||||
patch.object(R,'EXP',self.root).start()
|
||||
self.regfile=self.root/'protocol/preregistered.json';R.save(self.regfile,{'synthetic':True})
|
||||
self.sha=R.digest(self.regfile)
|
||||
self.w=R.Workflow.__new__(R.Workflow);self.w.sha=self.sha
|
||||
self.w.start=time.perf_counter();self.w.completed=set();self.w.expected=[];self.w.tasks={}
|
||||
self.w.overlay_dependency_pins={};self.w.case_dependency_pins={}
|
||||
self.w.reg=dict(budget=dict(output_cap_bytes=8<<20,minimum_free_reserve_bytes=0,
|
||||
workflow_timeout_seconds=60,child_timeout_seconds=10,not_after_utc='2099-01-01T00:00:00+00:00',
|
||||
next_child_headroom_bytes=65536),runtime_input_sha256={},
|
||||
input_sha256={},initial_overlay=dict(overlay_file=str(self.root/'protocol/zero.npz'),
|
||||
overlay_manifest=str(self.root/'protocol/zero.json')))
|
||||
R.save_npz(self.root/'protocol/zero.npz',dict(plastic_delta_mv=np.zeros(2,np.float32)))
|
||||
R.save(self.root/'protocol/zero.json',dict(synthetic=True))
|
||||
initial={p.relative_to(self.root).as_posix():R.identity(p) for p in (self.root/'protocol').iterdir()}
|
||||
self.w.ledger=R.Ledger(self.root,self.sha,initial,8<<20,0)
|
||||
|
||||
def test_original_composer_no_US_D0_frozen_and_PPL_requests(self):
|
||||
cs=dict(tick=np.array([10,20],np.int32),neuron_idx=np.array([3,4],np.int32))
|
||||
for arm,requested,dan in (('paired',False,'PAM15'),('d_zero',True,'PAM15'),
|
||||
('frozen',True,'PAM15'),('paired',True,'PPL103')):
|
||||
item=task(arm,requested=requested,dan=dan)
|
||||
ids=np.array([10,11,12,13] if dan=='PAM15' else [14,15],np.int32)
|
||||
composed,us=R.compose_requests(cs,ids,item,COMPOSER)
|
||||
self.assertEqual(len(us['tick']),len(ids) if requested else 0)
|
||||
self.assertEqual(composed['audit']['US_attempts'],len(us['tick']))
|
||||
self.assertEqual(item['recipe']['D_command'],0. if not requested or arm=='d_zero' else 1.)
|
||||
self.assertEqual(item['recipe']['update_enabled'],arm!='frozen')
|
||||
if requested:self.assertTrue(np.array_equal(us['neuron_idx'],ids))
|
||||
bad=task('d_zero');bad['recipe']['D_command']=1.
|
||||
with self.assertRaisesRegex(ValueError,'D/update'):R.compose_requests(cs,ids,bad,COMPOSER)
|
||||
|
||||
def test_probe_refuses_US_update_or_feedback(self):
|
||||
cs=dict(tick=np.array([7],np.int32),neuron_idx=np.array([3],np.int32))
|
||||
value=task(kind='probe');combined,us=R.compose_requests(cs,np.array([9,10],np.int32),value,COMPOSER)
|
||||
self.assertEqual(len(us['tick']),0);self.assertEqual(combined['audit']['US_attempts'],0)
|
||||
for role in ('US_requested','weight_updates_enabled','feedback_to_training_or_idle'):
|
||||
bad=copy.deepcopy(value)
|
||||
(bad if role=='feedback_to_training_or_idle' else bad['recipe'])[role]=True
|
||||
with self.assertRaisesRegex(ValueError,'Probe command'):R.compose_requests(cs,np.array([9,10],np.int32),bad,COMPOSER)
|
||||
|
||||
def test_frozen_clock_and_reset_seed_retained(self):
|
||||
original=dict(kind='fullgraph',dt_ms=.1,apl_delay_steps=18,precision='float64',
|
||||
apl_precision='float32',record_history=False,seed=1234,training=False,cs_input_seed=999)
|
||||
actual=R.derive_spec(original,task(),budget_root=self.root,output_cap=123456)
|
||||
self.assertEqual(actual['seed'],1234);self.assertEqual(actual['steps'],1200)
|
||||
self.assertEqual(actual['duration_ms'],120.);self.assertNotIn('cs_input_seed',actual)
|
||||
self.assertFalse(actual['within_trial_weight_updates']);self.assertFalse(original['training'])
|
||||
with self.assertRaisesRegex(ValueError,'fixed D18'):R.derive_spec(dict(original,apl_delay_steps=0),task(),budget_root=self.root,output_cap=1)
|
||||
|
||||
def test_actual_successful_parent_receipt_commits_ledger(self):
|
||||
output=self.root/'runs/synthetic.txt'
|
||||
job=dict(kind='cpu_verify',input_sha256={str(self.regfile):self.sha})
|
||||
def fake_run(argv,**kwargs):
|
||||
self.assertEqual(kwargs['env']['CUDA_VISIBLE_DEVICES'],'')
|
||||
self.assertEqual(kwargs['env']['PYTHONDONTWRITEBYTECODE'],'1')
|
||||
kwargs['stdout'].write(b'synthetic child only\n');output.write_bytes(b'new immutable output')
|
||||
return SimpleNamespace(returncode=0)
|
||||
with patch.object(R.subprocess,'run',side_effect=fake_run) as run:
|
||||
self.w.launch('unit',job,['not-a-real-executable'],[output])
|
||||
self.assertEqual(run.call_count,1);self.assertIn('unit',self.w.completed)
|
||||
self.assertTrue(self.w.ledger.final_verify(['unit'])['pass_all'])
|
||||
process=R.read(self.root/'receipts/unit/process.json')
|
||||
self.assertEqual(process['exit_code'],0);self.assertTrue(process['complete'])
|
||||
with self.assertRaisesRegex(ValueError,'rerun committed'):
|
||||
self.w.launch('unit',job,['not-real'],[output])
|
||||
|
||||
def test_failed_child_is_uncommitted_unknown_and_cannot_rerun(self):
|
||||
job=dict(kind='cpu_verify',input_sha256={str(self.regfile):self.sha})
|
||||
with patch.object(R.subprocess,'run',return_value=SimpleNamespace(returncode=9)):
|
||||
with self.assertRaisesRegex(ValueError,'Child failed'):self.w.launch('failed',job,['not-real'],[])
|
||||
receipt=R.read(self.root/'receipts/failed/process.json')
|
||||
self.assertFalse(receipt['complete']);self.assertEqual(receipt['exit_code'],9)
|
||||
self.assertEqual(self.w.ledger.inspect()['uncommitted_entry_ids'],['failed'])
|
||||
with self.assertRaises(FileExistsError):self.w.launch('failed',job,['not-real'],[])
|
||||
|
||||
def test_timed_out_child_never_gets_success_commit(self):
|
||||
job=dict(kind='cpu_verify',input_sha256={str(self.regfile):self.sha})
|
||||
with patch.object(R.subprocess,'run',side_effect=subprocess.TimeoutExpired('not-real',10)):
|
||||
with self.assertRaisesRegex(ValueError,'Child failed'):self.w.launch('timeout',job,['not-real'],[])
|
||||
receipt=R.read(self.root/'receipts/timeout/process.json')
|
||||
self.assertTrue(receipt['timed_out']);self.assertIsNone(receipt['exit_code'])
|
||||
self.assertNotIn('timeout',self.w.completed)
|
||||
|
||||
def test_spawn_OSerror_retains_failed_receipt_without_fake_exit(self):
|
||||
job=dict(kind='cpu_verify',input_sha256={str(self.regfile):self.sha})
|
||||
with patch.object(R.subprocess,'run',side_effect=OSError('synthetic spawn failure')):
|
||||
with self.assertRaisesRegex(ValueError,'Child failed'):self.w.launch('spawn-error',job,['not-real'],[])
|
||||
receipt=R.read(self.root/'receipts/spawn-error/process.json')
|
||||
self.assertFalse(receipt['complete']);self.assertIsNone(receipt['exit_code'])
|
||||
self.assertFalse(receipt['exit_observed_by_parent']);self.assertIn('synthetic spawn failure',receipt['launch_error'])
|
||||
self.assertEqual(self.w.ledger.inspect()['uncommitted_entry_ids'],['spawn-error'])
|
||||
|
||||
def test_after_process_input_mutation_stops_before_commit(self):
|
||||
dependency=self.root/'protocol/input.json';R.save(dependency,dict(value=1))
|
||||
job=dict(kind='cpu_verify',input_sha256={str(dependency):R.digest(dependency)})
|
||||
def fake_run(*a,**k):
|
||||
dependency.write_bytes(b'{"value":2}');return SimpleNamespace(returncode=0)
|
||||
with patch.object(R.subprocess,'run',side_effect=fake_run):
|
||||
with self.assertRaisesRegex(ValueError,'Pinned input changed'):self.w.launch('mutation',job,['not-real'],[])
|
||||
self.assertNotIn('mutation',self.w.completed)
|
||||
|
||||
def _delta_fixture(self):
|
||||
old=task();new=task(number=2);new['delta_dependency']=dict(kind='epoch_delta_after',source=old['task_id']+'/delta-after')
|
||||
self.w.tasks={old['task_id']:old};key=R.task_key(old)
|
||||
self.w.completed.add(key+'--verify')
|
||||
output=self.root/'updates'/key;output.mkdir()
|
||||
R.save_npz(output/'delta-after.npz',dict(plastic_delta_mv=np.array([-.25,0.],np.float32)))
|
||||
R.save(output/'overlay-manifest.json',dict(synthetic=True))
|
||||
validation=self.root/'validation/previous.json';R.save(validation,dict(complete=True,
|
||||
after_overlay_sha256=R.digest(output/'delta-after.npz'),after_manifest_sha256=R.digest(output/'overlay-manifest.json')))
|
||||
process=self.root/f'receipts/{key}--verify/process.json';process.parent.mkdir()
|
||||
R.save(process,dict(complete=True,exit_code=0,
|
||||
entry_id=key+'--verify',registration_sha256=self.sha))
|
||||
overlay=dict(overlay_file=str(output/'delta-after.npz'),overlay_manifest=str(output/'overlay-manifest.json'))
|
||||
result=self.root/f'results/{key}.json'
|
||||
R.save(result,dict(complete=True,task=old,cpu_validation=R.pin(validation),after_overlay=overlay,
|
||||
cpu_process_receipt_path=str(process),update_dir=str(output)))
|
||||
for path in (result,validation,process,output/'delta-after.npz',output/'overlay-manifest.json'):
|
||||
self.w.ledger._tracked[path.relative_to(self.root).as_posix()]=R.identity(path)
|
||||
return old,new,overlay,result,validation
|
||||
|
||||
def test_delta_dependency_requires_same_branch_completed_verify_and_receipt(self):
|
||||
old,new,overlay,result,validation=self._delta_fixture()
|
||||
self.w.completed.clear()
|
||||
with self.assertRaisesRegex(ValueError,'CPU validation missing'):self.w.overlay(new)
|
||||
self.w.completed.add(R.task_key(old)+'--verify')
|
||||
self.assertEqual(self.w.overlay(new),overlay)
|
||||
self.assertIn(str(result),self.w.overlay_dependency_pins)
|
||||
self.assertIn(str(validation),self.w.overlay_dependency_pins)
|
||||
for field in ('arm','block_id'):
|
||||
altered=copy.deepcopy(new);altered[field]='unrelated'
|
||||
with self.assertRaisesRegex(ValueError,'unrelated branch'):self.w.overlay(altered)
|
||||
validation.write_bytes(b'{}')
|
||||
with self.assertRaisesRegex(ValueError,'committed bytes'):self.w.overlay(new)
|
||||
|
||||
def test_alternate_valid_overlay_cannot_replace_previous_verified_delta(self):
|
||||
_,new,_,result,_=self._delta_fixture()
|
||||
alternative=self.root/'updates/other-valid';alternative.mkdir()
|
||||
R.save_npz(alternative/'delta-after.npz',dict(plastic_delta_mv=np.array([-.5,0.],np.float32)))
|
||||
R.save(alternative/'overlay-manifest.json',dict(synthetic=True,other=True))
|
||||
for path in alternative.iterdir():self.w.ledger._tracked[path.relative_to(self.root).as_posix()]=R.identity(path)
|
||||
record=R.read(result);record['update_dir']=str(alternative)
|
||||
record['after_overlay']={k:str(alternative/name) for k,name in
|
||||
(('overlay_file','delta-after.npz'),('overlay_manifest','overlay-manifest.json'))}
|
||||
result.write_text(R.canonical(record),encoding='utf-8')
|
||||
with self.assertRaisesRegex(ValueError,'committed bytes'):self.w.overlay(new)
|
||||
# Even a synthetic "committed" bad result must fail its independent CPU output binding.
|
||||
self.w.ledger._tracked[result.relative_to(self.root).as_posix()]=R.identity(result)
|
||||
with self.assertRaisesRegex(ValueError,'independently verified output'):self.w.overlay(new)
|
||||
|
||||
def test_zero_dependency_does_not_carry_previous_lineage_pins(self):
|
||||
self.w.overlay_dependency_pins={'stale':'0'*64}
|
||||
self.assertEqual(self.w.overlay(task()),self.w.reg['initial_overlay'])
|
||||
self.assertEqual(self.w.overlay_dependency_pins,{})
|
||||
|
||||
def _case_fixture(self):
|
||||
item=task();template=self.root/'protocol/case-template.json'
|
||||
R.save(template,dict(kind='fullgraph',dt_ms=.1,apl_delay_steps=18,precision='float64',
|
||||
apl_precision='float32',record_history=False,seed=1234))
|
||||
population=self.root/'protocol/populations.npz'
|
||||
self.w.populations=dict(PAM15=np.array([10,11,12,13],np.int32),PPL103=np.array([14,15],np.int32))
|
||||
R.save_npz(population,self.w.populations);self.w.reg['population_file']=str(population)
|
||||
self.w.reg['input_sha256'][str(population)]=R.digest(population)
|
||||
directory=self.root/'inputs/generated';directory.mkdir(parents=True)
|
||||
source=directory/'source.npz';audit=directory/'source.json'
|
||||
R.save_npz(source,dict(tick=np.array([5],np.int32),neuron_idx=np.array([3],np.int32)))
|
||||
descriptor=dict(synthetic=True)
|
||||
R.save(audit,dict(descriptor=descriptor,requests_sha256=R.digest(source)))
|
||||
self.w.input_plan=dict(task_inputs={item['task_id']:'source'},descriptors={'source':descriptor})
|
||||
self.w.inputs=COMPOSER
|
||||
for path in (template,population,source,audit):
|
||||
self.w.ledger._tracked[path.relative_to(self.root).as_posix()]=R.identity(path)
|
||||
return item,template,source,audit
|
||||
|
||||
def test_prepare_case_reads_only_committed_template_and_shared_CS(self):
|
||||
item,template,source,audit=self._case_fixture()
|
||||
directory=self.w.prepare_case(item)
|
||||
self.assertEqual(R.read(directory/'spec.json')['seed'],1234)
|
||||
self.assertTrue({str(template),str(source),str(audit)} <= set(self.w.case_dependency_pins))
|
||||
self.assertEqual(R.npz(directory/'us_requests.npz')['tick'].tolist(),[900]*4)
|
||||
|
||||
def test_changed_case_template_is_rejected_before_new_spec_write(self):
|
||||
item,template,_,_=self._case_fixture();value=R.read(template);value['seed']=9876
|
||||
template.write_text(R.canonical(value),encoding='utf-8')
|
||||
with self.assertRaisesRegex(ValueError,'committed bytes'):self.w.prepare_case(item)
|
||||
self.assertFalse((self.root/'cases'/R.task_key(item)/'spec.json').exists())
|
||||
|
||||
def test_changed_CS_and_self_rehashed_audit_are_both_rejected(self):
|
||||
item,_,source,audit=self._case_fixture()
|
||||
with source.open('wb') as stream:np.savez_compressed(stream,tick=np.array([9],np.int32),neuron_idx=np.array([4],np.int32))
|
||||
value=R.read(audit);value['requests_sha256']=R.digest(source)
|
||||
audit.write_text(R.canonical(value),encoding='utf-8')
|
||||
with self.assertRaisesRegex(ValueError,'committed bytes'):self.w.prepare_case(item)
|
||||
self.assertFalse((self.root/'cases'/R.task_key(item)/'requests.npz').exists())
|
||||
|
||||
def test_exclusive_helpers_reject_linked_parent_before_writes(self):
|
||||
destination=self.root/'external';destination.mkdir();link=self.root/'alias'
|
||||
try:link.symlink_to(destination,target_is_directory=True)
|
||||
except OSError:self.skipTest('Platform disallows temporary symlinks')
|
||||
for filename,write in (('x.json',lambda p:R.save(p,{'a':1})),
|
||||
('x.npz',lambda p:R.save_npz(p,{'a':np.array([1],np.int32)}))):
|
||||
with self.assertRaisesRegex(ValueError,'linked path'):write(link/filename)
|
||||
self.assertFalse((destination/filename).exists())
|
||||
|
||||
def _mock_task(self,item):
|
||||
"""Exercise real orchestration/control closures, with no scientific child."""
|
||||
validator=self.root/'validator.py';validator.write_bytes(b'# not executed\n')
|
||||
self.w.reg['input_sha256'][str(validator)]=R.digest(validator)
|
||||
patch.object(R,'AQ',self.root).start()
|
||||
target=self.root/'validate_update_cpu.py';target.write_bytes(validator.read_bytes())
|
||||
self.w.reg['input_sha256'][str(target)]=R.digest(target)
|
||||
for name in ('conditioning_epoch.py','conditioning_preflight_compare.py','engineering_compare.py'):
|
||||
self.w.reg['input_sha256'][str(LAB/name)]=R.digest(LAB/name)
|
||||
R.save(self.root/'protocol/epoch-template.json',dict(schema='synthetic',files={},frozen_inputs={}))
|
||||
self.w.ledger._tracked['protocol/epoch-template.json']=R.identity(self.root/'protocol/epoch-template.json')
|
||||
calls=[];authorities=[]
|
||||
def case(task_value):
|
||||
result=self.root/'cases'/R.task_key(task_value);result.mkdir()
|
||||
R.save(result/'spec.json',dict(steps=1200));R.save_npz(result/'requests.npz',dict(tick=np.empty(0,np.int32),neuron_idx=np.empty(0,np.int32)))
|
||||
return result
|
||||
def ap_job(name,kind,output,**kwargs):
|
||||
return dict(kind=kind,output_dir=str(output),receipt_file=str(self.root/f'receipts/{name}/worker.json'),
|
||||
input_sha256={},authority_file=str(kwargs.get('authority','')))
|
||||
def launch(name,job,argv,outputs,*,pre_outputs=(),post=None,ap=False):
|
||||
calls.append(job['kind'])
|
||||
if job['kind']=='brain':
|
||||
out=Path(job['output_dir']);out.mkdir();R.save(out/'checkpoint-manifest.json',dict(synthetic=True))
|
||||
R.save_npz(out/'state.npz',dict(step=np.empty(0,np.int32)))
|
||||
for filename in ('process.json','worker.json'):
|
||||
receipt=self.root/f'receipts/{name}/{filename}';receipt.parent.mkdir(exist_ok=True)
|
||||
R.save(receipt,dict(synthetic=True))
|
||||
self.w.ledger._tracked[receipt.relative_to(self.root).as_posix()]=R.identity(receipt)
|
||||
elif job['kind']=='update':
|
||||
authorities.append(R.read(job['authority_file']))
|
||||
out=Path(job['output_dir']);out.mkdir()
|
||||
R.save_npz(out/'delta-after.npz',dict(plastic_delta_mv=np.zeros(2,np.float32)))
|
||||
R.save(out/'overlay-manifest.json',{});R.save(out/'chain-receipt.json',{})
|
||||
else:
|
||||
out=Path(job['update_dir'])
|
||||
R.save(job['receipt_file'],dict(complete=True,frozen_U_verify_receipt_recomputed=True,
|
||||
actual_sealed_events_used=True,after_overlay_sha256=R.digest(out/'delta-after.npz'),
|
||||
epoch_authority_sha256=job['authority_sha256']))
|
||||
if post is not None:post()
|
||||
self.w.completed.add(name)
|
||||
with patch.object(self.w,'prepare_case',side_effect=case),patch.object(self.w,'ap_job',side_effect=ap_job),\
|
||||
patch.object(self.w,'launch',side_effect=launch),patch.object(self.w,'brain_verify',return_value={'synthetic':True}):
|
||||
self.w.task(item)
|
||||
return calls,authorities,R.read(self.root/f'results/{R.task_key(item)}.json')
|
||||
|
||||
def test_probe_orchestration_never_calls_E_or_CPU_update(self):
|
||||
calls,authorities,record=self._mock_task(task(kind='probe'))
|
||||
self.assertEqual(calls,['brain']);self.assertEqual(authorities,[])
|
||||
self.assertNotIn('after_overlay',record);self.assertNotIn('cpu_validation',record)
|
||||
|
||||
def test_training_no_US_preserves_None_and_zero_D(self):
|
||||
calls,authorities,record=self._mock_task(task(requested=False))
|
||||
self.assertEqual(calls,['brain','update','cpu_verify'])
|
||||
self.assertIsNone(authorities[0]['command']['us_tick'])
|
||||
self.assertEqual(authorities[0]['command']['d_command'],0.)
|
||||
self.assertFalse(authorities[0]['command']['frozen']);self.assertIn('after_overlay',record)
|
||||
|
||||
def test_D0_keeps_US_but_passes_zero_D_to_original_E(self):
|
||||
calls,authorities,_=self._mock_task(task('d_zero'))
|
||||
self.assertEqual(calls,['brain','update','cpu_verify'])
|
||||
self.assertEqual(authorities[0]['command']['us_tick'],900)
|
||||
self.assertEqual(authorities[0]['command']['d_command'],0.)
|
||||
self.assertFalse(authorities[0]['command']['frozen'])
|
||||
|
||||
def test_frozen_keeps_D_request_but_explicitly_disables_update(self):
|
||||
_,authorities,_=self._mock_task(task('frozen'))
|
||||
self.assertEqual(authorities[0]['command']['d_command'],1.)
|
||||
self.assertTrue(authorities[0]['command']['frozen'])
|
||||
|
||||
def test_PPL_compartment_not_replaced_by_PAM_or_sign_flip(self):
|
||||
_,authorities,_=self._mock_task(task(dan='PPL103'))
|
||||
self.assertEqual(authorities[0]['command']['compartment'],"y2a'1")
|
||||
self.assertEqual(authorities[0]['command']['d_command'],1.)
|
||||
self.assertEqual(authorities[0]['command']['trace_backend'],'torch')
|
||||
|
||||
def test_partial_task_cannot_silently_resume_remaining_children(self):
|
||||
item=task();self.w.completed.add(R.task_key(item)+'--brain')
|
||||
with patch.object(self.w,'launch') as launch:
|
||||
with self.assertRaisesRegex(ValueError,'Partially completed task'):self.w.task(item)
|
||||
launch.assert_not_called()
|
||||
|
||||
def test_real_AP_validation_accepts_brain_job_and_rejects_protected_outputs(self):
|
||||
# Actual frozen parser only, using small synthetic files, no runtime load.
|
||||
frozen=self.root/'frozen';frozen.mkdir();graph=frozen/'graph';graph.mkdir();apl=frozen/'apl';apl.mkdir()
|
||||
for name in WORKER.GRAPH_FILES:(graph/name).write_bytes(b'synthetic graph bytes')
|
||||
for name in WORKER.APL_FILES:(apl/name).write_bytes(b'synthetic APL bytes')
|
||||
for name in ('mask.npy','base.npy','coeff.json'):(frozen/name).write_bytes(b'synthetic authority')
|
||||
case=self.root/'cases/first';case.mkdir()
|
||||
R.save(case/'spec.json',dict(graph_dir=str(graph),apl_bundle_dir=str(apl),coefficients_path=str(frozen/'coeff.json')))
|
||||
R.save_npz(case/'requests.npz',dict(tick=np.empty(0,np.int32),neuron_idx=np.empty(0,np.int32)))
|
||||
overlay=self.w.reg['initial_overlay'];manifest=Path(overlay['overlay_manifest'])
|
||||
am=LAB.parent/'wholebrain-plastic-interface-v1/overlay.py'
|
||||
manifest.write_text(R.canonical(dict(mask_path=str(frozen/'mask.npy'),mask_sha256=R.digest(frozen/'mask.npy'),
|
||||
base_candidate_path=str(frozen/'base.npy'),base_candidate_sha256=R.digest(frozen/'base.npy'),
|
||||
am_overlay_path=str(am),am_overlay_sha256=R.digest(am))),encoding='utf-8')
|
||||
self.w.reg['runtime_input_sha256']={p:v['sha256'] for p,v in R.inventory(frozen).items()}
|
||||
self.w.reg['runtime_input_sha256'][str(am)]=R.digest(am);self.w.h=WORKER
|
||||
name='parser-brain';job=self.w.ap_job(name,'brain',self.root/'runs/first',case=case,overlay=overlay)
|
||||
Path(job['receipt_file']).parent.mkdir()
|
||||
file=self.root/'jobs/parser.json';R.save(file,job)
|
||||
parsed,paths,_,_=WORKER.validate_job(file,R.digest(file),'brain')
|
||||
self.assertEqual(parsed['diagnostic_mode'],'light');self.assertFalse(paths['output'].exists())
|
||||
for field in ('output_dir','receipt_file','build_root'):
|
||||
altered=copy.deepcopy(job);altered[field]=str(case/('forbidden-'+field))
|
||||
alternative=self.root/'jobs'/(field+'.json');R.save(alternative,altered)
|
||||
with self.assertRaisesRegex(ValueError,'protected input/source'):
|
||||
WORKER.validate_job(alternative,R.digest(alternative),'brain')
|
||||
self.assertFalse((case/'forbidden-output_dir').exists())
|
||||
|
||||
def test_separate_receipt_directories_allow_original_worker_lineage_protection(self):
|
||||
# Real AP path validator should not interpret a previous receipt as
|
||||
# authorizing writes into its parent. New receipts must be siblings.
|
||||
prior=self.root/'receipts/previous';prior.mkdir()
|
||||
previous=prior/'process.json';R.save(previous,dict(synthetic=True))
|
||||
self.w.overlay_dependency_pins={str(previous):R.digest(previous)}
|
||||
self.test_real_AP_validation_accepts_brain_job_and_rejects_protected_outputs()
|
||||
|
||||
|
||||
if __name__=='__main__':unittest.main()
|
||||
@@ -0,0 +1,37 @@
|
||||
"""Pure temporary-file supervisor bookkeeping tests, no actual child launch."""
|
||||
from pathlib import Path
|
||||
import tempfile
|
||||
from types import SimpleNamespace
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
import run_normal as R
|
||||
|
||||
class SupervisorTests(unittest.TestCase):
|
||||
def test_launch_is_exclusive_not_completion(self):
|
||||
with tempfile.TemporaryDirectory() as temp,patch.object(R,'CONTROL',Path(temp)),patch.object(R,'authority',return_value={}):
|
||||
with patch.object(R.subprocess,'Popen',return_value=SimpleNamespace(pid=123)) as spawn:
|
||||
record=R.launch('a'*64)
|
||||
self.assertEqual(spawn.call_count,1)
|
||||
self.assertTrue(spawn.call_args.kwargs['start_new_session'])
|
||||
self.assertFalse(record['final_exit_observed'])
|
||||
self.assertFalse((Path(temp)/'exit.json').exists())
|
||||
with self.assertRaises(ValueError):R.launch('a'*64)
|
||||
self.assertEqual(spawn.call_count,1)
|
||||
|
||||
def test_final_exit_is_parent_observed_not_learning(self):
|
||||
with tempfile.TemporaryDirectory() as temp,patch.object(R,'CONTROL',Path(temp)),patch.object(R,'authority',return_value={}):
|
||||
with patch.object(R.subprocess,'run',return_value=SimpleNamespace(returncode=0)):
|
||||
self.assertEqual(R.supervise('b'*64),0)
|
||||
record=R.read(Path(temp)/'exit.json')
|
||||
self.assertTrue(record['complete'] and record['final_exit_observed'])
|
||||
self.assertFalse(record['learning_success_claimed'])
|
||||
|
||||
def test_failed_spawn_has_no_fabricated_exit(self):
|
||||
with tempfile.TemporaryDirectory() as temp,patch.object(R,'CONTROL',Path(temp)),patch.object(R,'authority',return_value={}):
|
||||
with patch.object(R.subprocess,'run',side_effect=OSError('fixture')):
|
||||
self.assertEqual(R.supervise('b'*64),1)
|
||||
record=R.read(Path(temp)/'exit.json')
|
||||
self.assertIsNone(record['exit_code'])
|
||||
self.assertFalse(record['complete'] or record['final_exit_observed'])
|
||||
|
||||
if __name__=='__main__':unittest.main()
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"fresh_E_seconds": 4.8041809019996435,
|
||||
"fresh_V_seconds": 4.153049107000697,
|
||||
"label": "M",
|
||||
"original_fresh_validator_actual_exit": 0,
|
||||
"position": 0,
|
||||
"resident_E_seconds": 4.331270731003315,
|
||||
"resident_V_seconds": 3.5904566640019766,
|
||||
"update_comparison": {
|
||||
"all_four_files_SHA_identical": true,
|
||||
"arrays_bitwise_identical": true,
|
||||
"full_update_receipt_and_trace_digests_identical": true
|
||||
},
|
||||
"validator_comparison": {
|
||||
"all_scientific_fields_identical": true,
|
||||
"explicit_differing_fields": [
|
||||
"schema",
|
||||
"validator_source",
|
||||
"original_validator_source",
|
||||
"resident_prototype",
|
||||
"resident_cache_scope"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"fresh_E_seconds": 4.551296638994245,
|
||||
"fresh_V_seconds": 3.902626559000055,
|
||||
"label": "N",
|
||||
"original_fresh_validator_actual_exit": 0,
|
||||
"position": 1,
|
||||
"resident_E_seconds": 2.678891448005743,
|
||||
"resident_V_seconds": 2.062450468001771,
|
||||
"update_comparison": {
|
||||
"all_four_files_SHA_identical": true,
|
||||
"arrays_bitwise_identical": true,
|
||||
"full_update_receipt_and_trace_digests_identical": true
|
||||
},
|
||||
"validator_comparison": {
|
||||
"all_scientific_fields_identical": true,
|
||||
"explicit_differing_fields": [
|
||||
"schema",
|
||||
"validator_source",
|
||||
"original_validator_source",
|
||||
"resident_prototype",
|
||||
"resident_cache_scope"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"fresh_E_seconds": 4.735514142004831,
|
||||
"fresh_V_seconds": 4.103694833996997,
|
||||
"label": "M",
|
||||
"original_fresh_validator_actual_exit": 0,
|
||||
"position": 2,
|
||||
"resident_E_seconds": 2.857203049999953,
|
||||
"resident_V_seconds": 2.14666489699448,
|
||||
"update_comparison": {
|
||||
"all_four_files_SHA_identical": true,
|
||||
"arrays_bitwise_identical": true,
|
||||
"full_update_receipt_and_trace_digests_identical": true
|
||||
},
|
||||
"validator_comparison": {
|
||||
"all_scientific_fields_identical": true,
|
||||
"explicit_differing_fields": [
|
||||
"schema",
|
||||
"validator_source",
|
||||
"original_validator_source",
|
||||
"resident_prototype",
|
||||
"resident_cache_scope"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"fresh_E_seconds": 4.5949991710003815,
|
||||
"fresh_V_seconds": 3.924993649998214,
|
||||
"label": "N_D0",
|
||||
"original_fresh_validator_actual_exit": 0,
|
||||
"position": 3,
|
||||
"resident_E_seconds": 2.6922046239997144,
|
||||
"resident_V_seconds": 1.9751014260036754,
|
||||
"update_comparison": {
|
||||
"all_four_files_SHA_identical": true,
|
||||
"arrays_bitwise_identical": true,
|
||||
"full_update_receipt_and_trace_digests_identical": true
|
||||
},
|
||||
"validator_comparison": {
|
||||
"all_scientific_fields_identical": true,
|
||||
"explicit_differing_fields": [
|
||||
"schema",
|
||||
"validator_source",
|
||||
"original_validator_source",
|
||||
"resident_prototype",
|
||||
"resident_cache_scope"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"fresh_E_seconds": 4.620397169004718,
|
||||
"fresh_V_seconds": 3.9045120619994123,
|
||||
"label": "N_frozen",
|
||||
"original_fresh_validator_actual_exit": 0,
|
||||
"position": 4,
|
||||
"resident_E_seconds": 2.7464958280033898,
|
||||
"resident_V_seconds": 2.027457176001917,
|
||||
"update_comparison": {
|
||||
"all_four_files_SHA_identical": true,
|
||||
"arrays_bitwise_identical": true,
|
||||
"full_update_receipt_and_trace_digests_identical": true
|
||||
},
|
||||
"validator_comparison": {
|
||||
"all_scientific_fields_identical": true,
|
||||
"explicit_differing_fields": [
|
||||
"schema",
|
||||
"validator_source",
|
||||
"original_validator_source",
|
||||
"resident_prototype",
|
||||
"resident_cache_scope"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"fresh_E_seconds": 4.764637047999713,
|
||||
"fresh_V_seconds": 4.06785895700159,
|
||||
"label": "M_D0",
|
||||
"original_fresh_validator_actual_exit": 0,
|
||||
"position": 5,
|
||||
"resident_E_seconds": 2.7973176640007296,
|
||||
"resident_V_seconds": 2.0859955760024604,
|
||||
"update_comparison": {
|
||||
"all_four_files_SHA_identical": true,
|
||||
"arrays_bitwise_identical": true,
|
||||
"full_update_receipt_and_trace_digests_identical": true
|
||||
},
|
||||
"validator_comparison": {
|
||||
"all_scientific_fields_identical": true,
|
||||
"explicit_differing_fields": [
|
||||
"schema",
|
||||
"validator_source",
|
||||
"original_validator_source",
|
||||
"resident_prototype",
|
||||
"resident_cache_scope"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"fresh_E_seconds": 4.7666301089993794,
|
||||
"fresh_V_seconds": 4.0638777050044155,
|
||||
"label": "M",
|
||||
"original_fresh_validator_actual_exit": 0,
|
||||
"position": 6,
|
||||
"resident_E_seconds": 2.8035546359969885,
|
||||
"resident_V_seconds": 2.0804165529989405,
|
||||
"update_comparison": {
|
||||
"all_four_files_SHA_identical": true,
|
||||
"arrays_bitwise_identical": true,
|
||||
"full_update_receipt_and_trace_digests_identical": true
|
||||
},
|
||||
"validator_comparison": {
|
||||
"all_scientific_fields_identical": true,
|
||||
"explicit_differing_fields": [
|
||||
"schema",
|
||||
"validator_source",
|
||||
"original_validator_source",
|
||||
"resident_prototype",
|
||||
"resident_cache_scope"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,308 @@
|
||||
{
|
||||
"CPU_only": true,
|
||||
"acceptance": "Exact four update files, bitwise delta, full trace/receipt identity, fresh original verifier exit0, separate resident verifier identity",
|
||||
"authorities": {
|
||||
"M": "/data/digital-drosophila/experiments/phase4aq-conditioning-execution/authorities/mechanical--fresh-parent.epoch.json",
|
||||
"M_D0": "/tmp/malecns-cpu-residency-woqIQa/inputs/M_D0.authority.json",
|
||||
"N": "/data/digital-drosophila/experiments/phase4aq-conditioning-execution/authorities/performance--natural-light-fresh.epoch.json",
|
||||
"N_D0": "/tmp/malecns-cpu-residency-woqIQa/inputs/N_D0.authority.json",
|
||||
"N_frozen": "/tmp/malecns-cpu-residency-woqIQa/inputs/N_frozen.authority.json"
|
||||
},
|
||||
"benchmark_scope": "CPU epoch postprocessing and verification only; excludes AP wrapper/ledger and all GPU/brain work",
|
||||
"current_AR_untouched": true,
|
||||
"derived_controls": "Only D=0/frozen command variants over fixed sealed events; not new brain runs",
|
||||
"fixture_selection": "Two predeclared complete frozen AQ engineering fixtures; never AR interim results",
|
||||
"input_sha256": {
|
||||
"/data/digital-drosophila/datasets/male-cns-v1.0/processed/neuron-only/neuron-index/unified-metadata.parquet": "922af16846a065c3dbfca7c11146b83ca217fcbd7392edc745f444a04eae8c63",
|
||||
"/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json": "bde79d95ef0097b827d5faf4d5658eafc009d8e9fcef1fddd645c953823e3f64",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/apl_globals.npy": "8388c8795d49cfe5b14fda54f76ef3a35030c62ba87bd8ca6334a2dcdf186f19",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/input_matrix.npy": "c4d3df703ea5f1d7402b8255cfa19d9744139ad1048827c23b151d8ba766fec6",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/kc_globals.npy": "97a570aafa089f93e642b2bb07e3a3322dabb14c3c7dd431f0c8d2b3b7951fdd",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/output_matrix.npy": "e2d0a1ccd740e6777245ebf2efcd88bf5e1da9e47308c63ec8e83d451e134a73",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/dst.npy": "ce20f7433f78442c717ad2a7b5394cf4a3b109d990b4be0788040b7b0f4ed150",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/edge_id.npy": "49260615ff2b6432ce3dea9ce2c7ab8f83d06c2fb7491e58e08355fcedf86a30",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/nodes.npy": "5b511a98e8fbf8d65bbc70b93e75ecae19366f650b7842a45611bfad62ed83dc",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/ptr.npy": "fe43420f11e6242a11f8199ae7f097cab4b8a6db181d36f2a46b9e46670acbb4",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/signed_raw.npy": "f9884ccb8930b32420b27c69271df78034a8350fe5a5c9b76a63c259268efc09",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/src.npy": "bfd625ce690fc21eb0a8b9dede831688ab73b789045ba83ddf4baeefeddf1fc3",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/weights.npy": "462839ffc3feb8f6c278044488082b1c8e410e7f23229d6b5e29d1b7042416a1",
|
||||
"/data/digital-drosophila/experiments/phase4ak-apl-timing-validation/cases/seed_validation/seed_validation-physiological-00-s1073741825/requests.npz": "003a6f6306787b67391735c41dd8b14c689beaaab3ab71a5e9afb376d3cbb091",
|
||||
"/data/digital-drosophila/experiments/phase4ak-apl-timing-validation/cases/seed_validation/seed_validation-physiological-00-s1073741825/spec.json": "ebffa677b41e06cb776a987a496a0577bdda135cf3c067ca8017b038ff3fc5c4",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/audit/final-status.json": "18b12c832e156bd6e5ba950f48a49fb908c62104b91bb3e78213f523c8fdc8f9",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/audit/scientific-summary.json": "03f229fc0768d38bb7c2a3c558dbd68c2c3a622cbf96b1b16aef2819b6b67b77",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/audit/static25-complete.json": "1a9cfd096bfc7ab826e043d450a32403a1a7176ab1f7056a3afaceb5c33ac098",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/audit/zero-complete.json": "59397f4b7874894049cc5e77d0555ddcc8274c9573bc53a4bc5f41429683166e",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/checksums.sha256": "fde235a6d781d4c860107c3aa94671811b3f39b167965034ed57f3278e012c3a",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/adapter-provenance.json": "d1b64bdd7b8bc2023dba8321f74bf8ba0a9cac8ded772711f68efeeeb2297156",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/apl-applied.float32.npy": "6228c9e8ec19cb7532e65728ec8f2bd6b080dca8379b17bd393979beaba4c6eb",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/apl-drive.float32.npy": "19b32ccdefea22ddc3e2efcc98b919b8fcf69887f029c17dc75bafa5b34259c5",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/apl-inhibition.float32.npy": "d5194ea98900ca1800416712619143b731d9b3a5d1391180e6881205c7a4d663",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/apl-pending-tail.float32.npy": "2dd2e0c79d4ee5299b8c1e8863e6c61b81f3dba08e599011887b1e1621f7c945",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/apl-state.float32.npy": "5fe5ac53e012232b42a7e717357e9782b247f74da93640a0cfb8a078bc9d4855",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/apl-timing-audit.json": "6ceacfab219fc40146c3e753bdaa96a9e678762f1aeeec04fa303cbf9ebc09be",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/comparison.json": "becda112d4f7576318e2a825daf8f049eb3916c964252511963779899228974c",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/output-hashes.json": "74748bb4cde4769caa31ecc7c888e9e6192fffc022deee94e4378573d0dbc9cc",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/overlay-audit.json": "949d7f986ae2212d44777bd351b88e54c38db857fc062d4d232c2670d31e3085",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/overlay-input.npz": "7805bd2f86de91777bca86c52870607a2e091ed74b901319b896055ad3463f6d",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/overlay-manifest.json": "96d8406b69e98ba9829a52788c6c96888493e8bf34581d6d653226b1eb2e494b",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/queue.jsonl": "3e93bbae67a18944383b2b11a63708ee31e18b8ae7084f24dcb24045c85aa9a7",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/requests.csv": "b11fb0b6d1ac9211f02f05a9809175c64b72e8bcd4c4e4da31be1efbe6a82a83",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/sealed-gpu-source.diff": "0584f865885b18e6a36870a7ecfbbc98d7a94274fa5e9e073e7cf97597d78a03",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/source-audit.json": "d644f0265632f117bba0e045d26fb266765b1d005a89426b6242f3de034be935",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/state.npz": "7de2f62ecbde41a11db5aa220aed2fa6128e9fb6e65d04357f5373eb21538f81",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/summary.json": "6f6fb3ffc5f9df761a7972aa97444c7c095edb359580d19103044fa54bce674f",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/tick-state-hashes.jsonl": "3428c112a32024b539218aa6f4778cfa8c19c208bbdbfb2567324294370f23ea",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/adapter-provenance.json": "46d8ad74b409145c42f9066f992166f114cef2272bb0c6ea40c58438bdd39c13",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/apl-applied.float32.npy": "b3a535bc095db2464a75560ed11f336a9db8e843c08fd7681a1b9759b624ad8e",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/apl-drive.float32.npy": "8b6432e8947f4c67466b5cae28cb0d0877b61862e80e6d9b10c5734d9afa8411",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/apl-inhibition.float32.npy": "8f9e59026dc7c7663abf8f7abc60ebf93b11a68483bc0960d375a83731acc859",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/apl-pending-tail.float32.npy": "fc1e2d8ffa426d4118a7544129323c5f7523e9df3e298a60922ca0ecabe7c18f",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/apl-state.float32.npy": "36ecfec747be0c700959ba1ac171b81a1f3471aa9baba41b7bb6a67be01213c2",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/apl-timing-audit.json": "850600c0560f98c1f2de35bae506c5619205375e6616137a7e8ff978000b0c3a",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/comparison.json": "3e55e8edaf7e3cf4453e37cf90d7a420808977665174ccf525dfef7553418d46",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/output-hashes.json": "aabd9f46a9697440f0cc0204455e831d16b7aadfdebe3e5a8c986bfe85d05300",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/overlay-audit.json": "22d13f7d6ad27cbe117e01117d46c0457781adf3a0bf2aa6748fe7f4b484aa56",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/overlay-input.npz": "0b219eab09c30dc3af31fef7e6395a9bec1234090abbb72db096da833fed82c5",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/overlay-manifest.json": "902933628aabc9e084b547dfdaff0f8361d353949ba3ee92439a2f35d8625d8a",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/queue.jsonl": "22fbf106279d5ad314beba357137701df111bb28b57accdb09a0e299dfdf39cf",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/requests.csv": "4bcc9ef7fdc596ddac3be3b0d29f0aea2e086deeb803f3a90baba21b5490ef53",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/sealed-gpu-source.diff": "0584f865885b18e6a36870a7ecfbbc98d7a94274fa5e9e073e7cf97597d78a03",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/source-audit.json": "d644f0265632f117bba0e045d26fb266765b1d005a89426b6242f3de034be935",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/state.npz": "933afdc1bd0ea81174aeb334f017cfbe1bbc0a72f8eca767698275c5dca886f3",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/summary.json": "244be6a69b8276a212b1601ab7235e58c0bd9d523c88368025b29f4b4664ddcf",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/tick-state-hashes.jsonl": "0266afe78eadd1ea5bfb25026103d01d2af82d9b6ce2bcbb9d60e576ac898e91",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/manifest.json": "9e24b682935a9b18e05db7a933080c5f63ddbeb8a0c85cc0df1cfe1d06d88ab4",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/overlays/static25.json": "96d8406b69e98ba9829a52788c6c96888493e8bf34581d6d653226b1eb2e494b",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/overlays/static25.npz": "7805bd2f86de91777bca86c52870607a2e091ed74b901319b896055ad3463f6d",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/overlays/zero.json": "902933628aabc9e084b547dfdaff0f8361d353949ba3ee92439a2f35d8625d8a",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/overlays/zero.npz": "0b219eab09c30dc3af31fef7e6395a9bec1234090abbb72db096da833fed82c5",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/protocol/base-candidate.float32-mV.npy": "1218d1b328f29a7afefb0ca0b7b6421247f14ad598aa1957a6a7aacbc8cebcae",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/protocol/prepared-hashes.json": "4af0bccbb9153be0d8cb65c5e4150946be3396ca351eab52b273c86459200580",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/protocol/preregistered.json": "465886b78ada08092c2c83de278844707499718977fb6dc6a7608391da0e5304",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/regression/frozen-five.json": "905c64c8b3f7de942d55f6ecb76c27c42821691a9fd3e0c17ffb466e1de0fea0",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/regression/old-integrity-after.json": "7d3de4ba6248cc52960087bcfa2658f9b8ee34d9ac08c56380f7018c34097929",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/regression/old-integrity-before.json": "7d3de4ba6248cc52960087bcfa2658f9b8ee34d9ac08c56380f7018c34097929",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s00/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s00/template-spec.json": "065e4b01b74ac6619f6533c54fdb58a345fffe7be30ae2295e50ab7015da888a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s01/requests.npz": "929f5b8a23043c0a10790d7cc0683ff81a6049b4e714db86b1fb54cb7f3ca8f2",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s01/template-spec.json": "38001935f07393a08f8c83595541a6ff060b0f9ca7b9fdaf357e2f77f9348994",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s02/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s02/template-spec.json": "c89d7994d40fc79591c78d11c549766b45d283145fdcebb1e3b6c964b8750b2a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s03/requests.npz": "be049a344735ad19157ea86c6e911ea9042127ace736fe98bcdddf6b3c1425d1",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s03/template-spec.json": "390f3d472a2baf3b7d14f1bb22185e027fb1c5ede8f42bfbd8e7c2051e78d0fe",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s04/requests.npz": "764259eb618a2ee9393b67ec2713cd0c68763a3e55bbd35e261f5c38ea044b0e",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s04/template-spec.json": "90a262080e33a6014679e7f3d932f61e1edb04cffcd9a2cf35440c078a9085f4",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s00/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s00/template-spec.json": "3b63e236d755714dc59b083b2ee48761ce48e9a8456770e3502798f5bd5e2ff6",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s01/requests.npz": "929f5b8a23043c0a10790d7cc0683ff81a6049b4e714db86b1fb54cb7f3ca8f2",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s01/template-spec.json": "595a1a67fd82b48e0db25480771a93bd289e8f65c511c43780b42dabf9c8b478",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s02/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s02/template-spec.json": "bda9afb21aebd4cf37d52a0cb83c21f179ca4fe9aca8a43e5a1cc92f2af81897",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s03/requests.npz": "be049a344735ad19157ea86c6e911ea9042127ace736fe98bcdddf6b3c1425d1",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s03/template-spec.json": "246cbb287972c7539c4f53bc2546bd9cdd0dd960e8714bce060db1bee1ba0fc9",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s04/requests.npz": "764259eb618a2ee9393b67ec2713cd0c68763a3e55bbd35e261f5c38ea044b0e",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s04/template-spec.json": "de59abaa0670a9be8d90a9dd9b41522edd277d9f75dbdb77ddeeeca1c508265f",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--fresh--light-r0/requests.npz": "003a6f6306787b67391735c41dd8b14c689beaaab3ab71a5e9afb376d3cbb091",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--fresh--light-r0/template-spec.json": "802b717691f9a6b460a1a58044286e727ffa8393605127ee7a11ad267fbf6338",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--fresh--light-r1/requests.npz": "003a6f6306787b67391735c41dd8b14c689beaaab3ab71a5e9afb376d3cbb091",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--fresh--light-r1/template-spec.json": "f4cdfd5de0fb80dd39203425c4ff7d063b0b66f2ac887e4276043251e3ad956c",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--fresh--reference-r0/requests.npz": "003a6f6306787b67391735c41dd8b14c689beaaab3ab71a5e9afb376d3cbb091",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--fresh--reference-r0/template-spec.json": "2ee541997a8a82f9ac356e9fedf8fc70ce31f622d42d846ab6de8c5f6cdea39f",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--prefix--reference-t0018/requests.npz": "adc91d6f97531e8f94b0bbee6b67b1c62b0303bb90b2ad0aa0adf0af9f990570",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--prefix--reference-t0018/template-spec.json": "282eccfb1ee2008f0b9ae8cca4daf45bfefd664806e7d04b8712fadf90b83bb5",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--prefix--reference-t0019/requests.npz": "adc91d6f97531e8f94b0bbee6b67b1c62b0303bb90b2ad0aa0adf0af9f990570",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--prefix--reference-t0019/template-spec.json": "8cd7512a1b2cdef47aecfd26bfb7ee8b22b566dc6c6812e887b4cc3f5416e7e3",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--prefix--reference-t0500/requests.npz": "aa2773a740b0e85940f3d96738a141903d5d178e40586522b603ae1c9de53e98",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--prefix--reference-t0500/template-spec.json": "654043502385a40dc4396c25ab2bf6f74701a7026fc85e6789672a810e5f700e",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s00/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s00/template-spec.json": "e8f6fe8e0f67cbe851c045a067485d753979f5af32d30f596f545387b306f123",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s01/requests.npz": "929f5b8a23043c0a10790d7cc0683ff81a6049b4e714db86b1fb54cb7f3ca8f2",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s01/template-spec.json": "b727d54f9d28e9b8482860c3ed2bb6c30d4778fe90644b2df9ebb8d0c032e148",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s02/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s02/template-spec.json": "8af5bc5ed35084f15c7d77ded8224d49f49561d48510c862410eccd4d7dc5560",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s03/requests.npz": "be049a344735ad19157ea86c6e911ea9042127ace736fe98bcdddf6b3c1425d1",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s03/template-spec.json": "7e140b41ae610cd67a8cfe2e30d633190ac2c7689a4682bba676e423b54e689d",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s04/requests.npz": "764259eb618a2ee9393b67ec2713cd0c68763a3e55bbd35e261f5c38ea044b0e",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s04/template-spec.json": "5cc7905cdca67bdf09eb0730a274644f5605178b1c97928572c5ecf2a3b5acff",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s00/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s00/template-spec.json": "452da911a5f3d6d8cbd33e96451d6f65af5e46eee57fda00125c59f6378dfba6",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s01/requests.npz": "929f5b8a23043c0a10790d7cc0683ff81a6049b4e714db86b1fb54cb7f3ca8f2",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s01/template-spec.json": "b943e29941af75b7c4ff333bdc0a9697d0e15131bdea46c4460ef91f894565b2",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s02/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s02/template-spec.json": "412390b67001e08930f243f54954d78e7edf94b330aee2087c35748963a883db",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s03/requests.npz": "be049a344735ad19157ea86c6e911ea9042127ace736fe98bcdddf6b3c1425d1",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s03/template-spec.json": "6d5f2819be44646890cdad1969043bee5209e801b79687a8c1c2205601bc9656",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s04/requests.npz": "764259eb618a2ee9393b67ec2713cd0c68763a3e55bbd35e261f5c38ea044b0e",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s04/template-spec.json": "d8bd2b1b151582ec7495e59a15cae15279f71d444429c5c273397b63008b3440",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--fresh--light-r0/requests.npz": "003a6f6306787b67391735c41dd8b14c689beaaab3ab71a5e9afb376d3cbb091",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--fresh--light-r0/template-spec.json": "df1a6663ea748b0dc0333540877000e5c91d493b151e134e346dee54e834e3de",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--fresh--light-r1/requests.npz": "003a6f6306787b67391735c41dd8b14c689beaaab3ab71a5e9afb376d3cbb091",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--fresh--light-r1/template-spec.json": "32dce4105aaadac4f7079264cf0a30a3f8171862edf59cceaba6624f01a5252d",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--fresh--reference-r0/requests.npz": "003a6f6306787b67391735c41dd8b14c689beaaab3ab71a5e9afb376d3cbb091",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--fresh--reference-r0/template-spec.json": "a0bf214d782ddef0adb5b6f9b89c2d52566a5928b5d96316bddfe12520aa5460",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--prefix--reference-t0018/requests.npz": "adc91d6f97531e8f94b0bbee6b67b1c62b0303bb90b2ad0aa0adf0af9f990570",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--prefix--reference-t0018/template-spec.json": "8400934e175d3c20f19d863082e7df02c5279864b5191736565e9014df6e0e83",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--prefix--reference-t0019/requests.npz": "adc91d6f97531e8f94b0bbee6b67b1c62b0303bb90b2ad0aa0adf0af9f990570",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--prefix--reference-t0019/template-spec.json": "9c361dfb9af4dd7071a7f1c3c2315adddb21b42e9ed5e9a199b1cdf52fab40e7",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--prefix--reference-t0500/requests.npz": "aa2773a740b0e85940f3d96738a141903d5d178e40586522b603ae1c9de53e98",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--prefix--reference-t0500/template-spec.json": "bda640a599d6cdf80ad435f344fcd576d91ca0afe9de732f36fa7bd54d470c1e",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/overlays/static25.json": "b0ee003192fbdfd869f8b23c9bbab0ff99079b7bd2bf1dc33b7afef40785a143",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/overlays/zero.json": "11b668978f3070dad26d99d9310bebefa0731fa0d4e361e8dc0ef02a213277c2",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/AM-gate-authority.json": "66257eb665808e33005dd7ba14a16063064618cc48e47cb65b70f3900cec2484",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/AM-seal-verification.json": "175b5d0e2de12a9ce01c6167591dab882d9c9c6869de2d194bcd9e6732c6ed6d",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/ENGINEERING_GATE_DRAFT.md": "1ac0d65b906e1061781c967cc6a99e8a0a73df6a1ee564ed6603f88e3f5d7056",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_analysis.py": "3970d13bd43d4bc12baf4b6ad1cda3eb085e10bf4648752cfcecb6d12314c5ea",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_compare.py": "5a2403f11bc08d65a9d242ac2cf9686b850e0c3680d65659f785e9b6b50c0238",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_inputs.py": "cc8c0e83016af4836c81cd0773fc521c69fd30e6f4d021bf54d0e7897105c6d5",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_plan.py": "3c127aee723a054fda272fee458067608b521a7c443455822d97f509caded6c7",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_prepare.py": "62dedce2439407398e70beb4c718bf14e02d3e624b3db3ef6f74299115d84bc1",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_queue_audit.py": "6ddaec52f2a0b5d0c528d51230d372fe2344160aef5eccea6a95b6c5e61a574e",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_scopes.py": "1043ba217e5395c9e81e58b95a5aa396f572588872b954e549774f2b99cac5df",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_workflow.py": "76313332b8d18f121a61f7b6e2fc32ea9e893848e8ed5d049557fc08b385e674",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/runtime_continuation.py": "0b8e8e0a6a23a079dc62a88355ce355d53b3ae22f6665519a8f6aef2dcfc5aba",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/runtime_light.py": "522b8c31ea938890fe15364fccd25ccc5bded54101754909f255532e7ad01aae",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_analysis.py": "35e4ee37a1e82cf5e645d24165343049d400104c94a6d184b8aa834ba5ef2d20",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_compare.py": "87a85843d918cce6529ab94f7cb82499aa413281e803c00c030a3c340a581469",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_inputs.py": "4dcc7b775eb3c7e59ed9cc3d7591eacc0ef7bda1209edbd847e2ae79b115ef1b",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_plan.py": "c26c2c75bb27d3b8514b7d44f40369130d60147c6c8edc569b4efba4a4ad9815",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_prepare.py": "a12aa1d2cb4880a3f7a7889b89d71a859bc8c68b4badfb8f082d712cdd342627",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_queue_audit.py": "0e2bcfe25c3b5a5cd0ed5cd05a89392207191ec4db950cdb06a0137666c8adb7",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_scopes.py": "748c0777e4a8164e80c03c727df1c2decbac7747737ad1c9fb730ea5c9e208d3",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_workflow.py": "bb781b23f92b5c0eb92f8dbc54468a8e843177f6da004c444b48947b037bd705",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_runtime_continuation.py": "325c0b688d0ca1648ffdf29a8d3d4bb91d6f6115bea6f5ac30982acd6dfe8e06",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_runtime_light.py": "887345e497e6fa9c10ffa49c490196711d8cee028c62ec7a73f42db36569be2b",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/regression/old-integrity-before.json": "68475cc0e72039e044c8fb3aaea9c8487c6737c1b8a457641e818581d81c387c",
|
||||
"/data/digital-drosophila/experiments/phase4ao-conditioning-interface/inputs/static/candidate-map.npz": "29dcb57fcaefb5817fa4616b9a75285327b41d8a67cfc0f2ad2bacc14e41f2f0",
|
||||
"/data/digital-drosophila/experiments/phase4ap-conditioning-interface-v2/updates/D1--reference--epoch-000/delta-after.npz": "b89e407a5d93b5f1901f901b00428dc19bd20cee2d81e57b117a2fa68d200a48",
|
||||
"/data/digital-drosophila/experiments/phase4ap-conditioning-interface-v2/updates/D1--reference--epoch-000/overlay-manifest.json": "38dabc55ea0569843ee70f13cf570832ecaa8f1ee7f26a7420e7ebc3ea86f6bd",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/authorities/mechanical--fresh-parent.epoch.json": "4616a42c255ab839346368aa0e5e4306bb3878e55fcc95b176f058b1993c9b0c",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/authorities/performance--natural-light-fresh.epoch.json": "785e3d26d06b47efe7f054883d38fe2e13711195359bf9f4b03aa88887fbfb37",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/cases/mechanical--fresh-parent/requests.npz": "edabb35c72f41a72cad5965ba0a6789b56c9a4ce38b25d6c6a2811ec3981066b",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/cases/mechanical--fresh-parent/spec.json": "82d95a9d4f2933986ec30a02cb0a3e1c1b50a0d4eab47068ac1cde169986e57d",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/cases/performance--natural-light-fresh/requests.npz": "571d09c32cabd45af79f71f0f27f7adcc38b9c65daf5ca124366ea439e088143",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/cases/performance--natural-light-fresh/spec.json": "ea4c40897aceb26edfa5db934647fbc6f6946746441f843bc336f15e5d4e0a23",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/manifest.json": "2dc0feca75f718f2ee0d7c9240da503221823573fd25f1344d2fd97d97eb2db7",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/mechanical--fresh-parent/apl-applied.float32.npy": "017d0cd13616ce97ee46aec1cd0a80153e15d1a56cdbad19020b57db64a1281b",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/mechanical--fresh-parent/apl-component.json": "7a49a1a8fbe42b3965913b8e483ef729ba1f13c211f8da7f10b4b2cd142e6882",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/mechanical--fresh-parent/apl-drive.float32.npy": "09140f1cdb91af98894ff5592d5d346af82f2d82564150c46b10dfe5dd253cf5",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/mechanical--fresh-parent/apl-inhibition.float32.npy": "05b289e2d464765764cc8500bbb3c021fd87ce31124b4996c7290dd5ef6df90e",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/mechanical--fresh-parent/apl-pending-tail.float32.npy": "f988ec0eac0043a911c2489d5cd9f2ca08a5089dc3c8fdcea148b44b045a2f73",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/mechanical--fresh-parent/apl-state.float32.npy": "09140f1cdb91af98894ff5592d5d346af82f2d82564150c46b10dfe5dd253cf5",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/mechanical--fresh-parent/apl-timing-audit.json": "54507570ba3b668c0362c26858e2a426c258bbf763c06570c9ecdc531b53848c",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/mechanical--fresh-parent/checkpoint-manifest.json": "8814431d9e1afbf431affbe77c7e4402d43b5ece3063cd47696cb77249a295f5",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/mechanical--fresh-parent/finite-audit.json": "a230387da908449ff29f1acf53f3157ec4dee893208f32a424260d75924ad620",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/mechanical--fresh-parent/overlay-audit.json": "bb8ddbcdb4f17c36a7352f0aa863f68e0ba92c3c8507bd99b85df224035d9379",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/mechanical--fresh-parent/overlay-input.npz": "0b219eab09c30dc3af31fef7e6395a9bec1234090abbb72db096da833fed82c5",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/mechanical--fresh-parent/overlay-manifest.json": "11b668978f3070dad26d99d9310bebefa0731fa0d4e361e8dc0ef02a213277c2",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/mechanical--fresh-parent/queue.jsonl": "b9042219ea87c5bc89f53fc5710fa86a848de456088257182a20da33460bb05d",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/mechanical--fresh-parent/requests.csv": "c5ffaae03d4390faf7d7bb15dee8b5ce573c20538137ecb3464c652411400342",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/mechanical--fresh-parent/runtime-provenance.json": "3726d29c81de9823dc75ee676f1c17fcc2a649ae2d033fe45cb8f4ca6e5eeac7",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/mechanical--fresh-parent/sealed-gpu-source.diff": "0584f865885b18e6a36870a7ecfbbc98d7a94274fa5e9e073e7cf97597d78a03",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/mechanical--fresh-parent/source-audit.json": "d644f0265632f117bba0e045d26fb266765b1d005a89426b6242f3de034be935",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/mechanical--fresh-parent/state.npz": "de5740758c280d250714be96d0598dadf78434ae4b915ff3b6646bbd5219b201",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/mechanical--fresh-parent/summary.json": "c53d4dfc2befa3ed4dba5b6b93f2bea6de3a9fea3ae51371bd5a17576d315cc8",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/mechanical--fresh-parent/terminal-queues.npz": "c4cf2ea1e4c04ca06a85e830976fc5348e4723aea84751442bee12e3bef95ab2",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/mechanical--fresh-parent/tick-state-hashes.jsonl": "eea659b000781f96e89c2687a5ec4957d106b589cc20dfa8e6228f35697e6691",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/performance--natural-light-fresh/apl-component.json": "7a49a1a8fbe42b3965913b8e483ef729ba1f13c211f8da7f10b4b2cd142e6882",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/performance--natural-light-fresh/apl-pending-tail.float32.npy": "d26056012aaebe26ee9acdb2ee0ac226fa5496d87fe33c4378cc9359a0c5d5c8",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/performance--natural-light-fresh/apl-timing-audit.json": "92812c9cb2a35d53034799317a94c4d1f369968d378fe7806ba4b6d9c667e5ca",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/performance--natural-light-fresh/checkpoint-manifest.json": "5cec0f224be49493af884e969cb97d47ac3e000da88c6d0ac8d1b23e3025db8a",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/performance--natural-light-fresh/finite-audit.json": "5f0182167c4c628ec8fd6354a2fecde3dc99282894397aba155e7cb7e1fbce40",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/performance--natural-light-fresh/overlay-audit.json": "cfa98093495747b091d9863c5de8b30571ae4d9579771ed4a42b9fda72d2f912",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/performance--natural-light-fresh/overlay-input.npz": "b89e407a5d93b5f1901f901b00428dc19bd20cee2d81e57b117a2fa68d200a48",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/performance--natural-light-fresh/overlay-manifest.json": "38dabc55ea0569843ee70f13cf570832ecaa8f1ee7f26a7420e7ebc3ea86f6bd",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/performance--natural-light-fresh/requests.csv": "f448e63324feba55899e634b1ef79b89c80cb8842b1d2e38b74a198cb9af36f8",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/performance--natural-light-fresh/runtime-provenance.json": "164e4825ba0fb1aa02de73ad5bf7b0d7e28ece6180d77e0cae72c64826c483ea",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/performance--natural-light-fresh/sealed-gpu-source.diff": "0584f865885b18e6a36870a7ecfbbc98d7a94274fa5e9e073e7cf97597d78a03",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/performance--natural-light-fresh/source-audit.json": "d644f0265632f117bba0e045d26fb266765b1d005a89426b6242f3de034be935",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/performance--natural-light-fresh/state.npz": "137d5a73a869f27df8a3f97002ca6a683c80d3d715057759fb2aad64a05d37ff",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/performance--natural-light-fresh/summary.json": "6eaec94ddc0032e93a2e7d5bac4083ba05aa39e892b76b82c46cddd4d7f87759",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/performance--natural-light-fresh/terminal-queues.npz": "42dbeaa6f50c6d5e7492774393a2fcc8af775b682dd517a53535f6d7cd162c2c",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/updates/mechanical--fresh-parent/chain-receipt.json": "e1f5d70d1f0aa41edfecc8424603ef807770b3c8097570abdc1764b851e9c305",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/updates/mechanical--fresh-parent/delta-after.npz": "35b55ff715e797221163e812e4128a700eb05a4546d7f3f13dc5edc547aeb8e6",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/updates/mechanical--fresh-parent/overlay-manifest.json": "60f77f30609859a718db1004e6da1c23730736285c5a1d845ec0da97385b01be",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/updates/mechanical--fresh-parent/update-receipt.json": "d26c0fec7b1fcd8bbb5f7fb86b094c0870f1f0a4b29be1b3def77b66b6a3cbb5",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/updates/performance--natural-light-fresh/chain-receipt.json": "c4a45ddcfea6b1800ccb6f737733b7e13b726e54e8f10e145ac6787527fffd9e",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/updates/performance--natural-light-fresh/delta-after.npz": "af15c05aa9ce0fdcd2b47dcc8bef426a242f84efe7b45e79c345ff4d361d23b4",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/updates/performance--natural-light-fresh/overlay-manifest.json": "a98095968f62fe7375e5acab89dbfbf55de6a28760f93dc1f5b48f238a4c54c5",
|
||||
"/data/digital-drosophila/experiments/phase4aq-conditioning-execution/updates/performance--natural-light-fresh/update-receipt.json": "18c47fc5fceb4f1b52d601ed5114eec8239156677c44bfe364706a7e7d2fc972",
|
||||
"/data/digital-drosophila/experiments/phase4h-dopamine-plasticity/mappings/dan-to-compartment.parquet": "a16f72c3121ed0ec638c1a2b249ace446e6ccee020b49679818eb42589d00662",
|
||||
"/data/digital-drosophila/experiments/phase4h-dopamine-plasticity/mappings/dan-to-mbon-confirmed.parquet": "730d000f25667b59181d2ee6703c64591229a8beab0856197ed71e68d799d191",
|
||||
"/data/digital-drosophila/experiments/phase4h-dopamine-plasticity/mappings/mbon-to-compartment.parquet": "54f371f7e35b9def44becd1ba9bd2872861f4876b255b2c8ec46feee6473b70c",
|
||||
"/data/digital-drosophila/experiments/phase4h-dopamine-plasticity/plastic-mask/plastic-edge-candidates.parquet": "e5075ee3e5a0edf3a4d197453847163cc295b254f21c67203159bba204b12a76",
|
||||
"/data/digital-drosophila/experiments/phase4h-dopamine-plasticity/plastic-mask/plastic-edge-ids.int64.npy": "8b0fb6eb2e6c31da4d17dc20d890aa3f367e514f05642de5bad6b42a1611c05b",
|
||||
"/data/digital-drosophila/experiments/phase4l-olfactory-grounding/odor-encoder/frozen-odor-panel.parquet": "907f16a56e024a8e2112b5751e53b0e6037b329fa110098af3d31b119c10a1a0",
|
||||
"/data/digital-drosophila/experiments/phase4l-olfactory-grounding/odor-encoder/mapped-glomerular-vectors.npz": "f057563152e0fa22060080af13019f319e7f36563a775eff829bbc1929c451b0",
|
||||
"/data/digital-drosophila/experiments/phase4l-olfactory-grounding/odor-encoder/selection.json": "1b832becf9d08935716fe9ba5e3cd3e619e7d208dfb43c4fa197c969d095f113",
|
||||
"/data/digital-drosophila/experiments/phase4l-olfactory-grounding/receptor-mapping/olfactory-mapping.parquet": "a01d27000533e9844458a4c559cac084f1c34ca20a1104e97e6a0f72b0cc93b1",
|
||||
"/data/digital-drosophila/models/male-cns-lif/apl-timing-lab-v1/gpu_timing.py": "af1975ba5e5e700208c0a598d3cbe648a3cf10885c6231239b6e4b28f76d173b",
|
||||
"/data/digital-drosophila/models/male-cns-lif/apl-timing-lab-v1/timing_queue.py": "54df6d4818e2a0c26e96fb0aaf5d9b71cd964981706da937562d48af79aca14e",
|
||||
"/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/gpu_apl.py": "69f5d893f47dafff4ef7c3186c3df0b9014666b32c8f4e943b57016bec92b18a",
|
||||
"/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/legacy_apl_worker.py": "21ceec65fe42581dc55872010e0025d660e80358905f1cf4df1dadf341a3b291",
|
||||
"/data/digital-drosophila/models/male-cns-lif/author-fullgraph-lab-v1/oracle_full.py": "d72003d98f0f1624b12126eff50bd361c43d888f4a64d90ba9247a58976f1961",
|
||||
"/data/digital-drosophila/models/male-cns-lif/author-runtime-lab-v1/author_ext.cpp": "208a937d17bbb041b9bf6b25b89264ee566830b60609e58491b44583d8541f15",
|
||||
"/data/digital-drosophila/models/male-cns-lif/author-runtime-lab-v1/author_ext.cu": "669f166e18ce9a3f63fc723db8b0a8b74f7fa4757194b1bd65b4cf6008a7787e",
|
||||
"/data/digital-drosophila/models/male-cns-lif/author-runtime-lab-v1/gpu_backend.py": "03758d07572f4b44d272059d9308fac534268ad201b57bdd77d69fee95e67278",
|
||||
"/data/digital-drosophila/models/male-cns-lif/conditioning-execution-v1/validate_update_cpu.py": "44e95eca9e39e9cd25a1d5d2d46b2cea76e839143865a196f865a61fac700b9f",
|
||||
"/data/digital-drosophila/models/male-cns-lif/mb-physiology-v1/phase4j.py": "abb4574da85f00bd9ef61024c65993ef81d42651ff8d8d63c15dd69c6222471e",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/EVALUATION_POLICY_DRAFT.md": "a84170a61564715a1532f20df4c6a330f0f9725c383db48b8f3e1a4b5fba0bc8",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/EVIDENCE_DRAFT.md": "8455c12e3a6bb1b22a6e38f9017293fe5deea37ba3ec61e13598d00dafc12296",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/PROTOCOL_DRAFT.md": "8ebecb1f3d012ddc29a1cb727269dd277629c53565e09978bf9dbf7140cb8508",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/README_DRAFT.md": "50be97f64097b681355993a8afd7f467ea187e99e88b19ca30561e08d517999f",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/biological_contract.py": "e09f0f2b5e6ec746176e3a1aa2fdee1a15385e14e96bd343d14379a759f3ae43",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/conditioning_epoch.py": "757935a4815d9f625640df685184ed3fe44a8845323562796da7aa43cbb194e1",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/conditioning_inputs.py": "19382e066e450140bb653a3661f980ffe7cc62f412020ef57df0b6e6b3cbb8ba",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/conditioning_update.py": "96efff678cff910654eb08e86f1a17789e4e5589e340345f419c7027a7d547e2",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/draft-source-inventory.json": "2c72d47d09b4ad1949dc6cfdc170f64847ff75f95ded5d20b421fb5a75e0eb84",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/evaluation_plan.py": "991c813ff3322b230947f302b12b04ec382c3b632817f94b698101e4b17efa7d",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/evaluation_policy.py": "21331a9ff3567dc6f6399e16bb91ef486d74231f5db51799beb6dd1bf71d022b",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/metrics.py": "47319e21db3c8b030b1bafbf0703cd86fb588d23bb29436accbacdba73d08c3c",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/runtime_continuation.py": "0b8e8e0a6a23a079dc62a88355ce355d53b3ae22f6665519a8f6aef2dcfc5aba",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/runtime_light.py": "522b8c31ea938890fe15364fccd25ccc5bded54101754909f255532e7ad01aae",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/seed_registry.py": "0da033b132095ec3087b5d9f64e53c2e391fa50ab0b7653b31296eeb84799b7e",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_biological_contract.py": "0ce796e6ad1a4cbcb9bcb760eff628a9562b4a809cc9c177a9a0d88df68f02b3",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_conditioning_inputs.py": "95e37c770e78ce722a3007c5b371c51aec2989634cddfe5b414ac3fa817e5c22",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_conditioning_update.py": "1c25d93753932ace06abc876fe0867546b3bb330de3e602da6aec7bb4588e4bd",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_evaluation_plan.py": "21d2402025122d8665fb1f32e184fd8e30fc17242810fc70901b7f7fc8c53bfa",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_evaluation_policy.py": "421a31b76eaa547e890c291d2c38a415352d9ccad6fccc800461f522ff4c83f1",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_metrics.py": "1928894d248dd37fad0fc67bc9dcfeac27c4d8be4aec22f54b9ef20a10ea8645",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_seed_registry.py": "7aca38f3c975e3ad4f6337d83b826c09afef336381d124c22ff0eb2eb60a0834",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_trial_plan.py": "927678956ae9959a047b1cd258ee8dee22eb6842a96ff4b2ba2db077310163c9",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/trial_plan.py": "6fed3f494d075339a7e5b001d43b2598640b189e038952fbd4d41200bacac587",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-grounding-v1/phase4l.yaml": "9b8bcb7e031bf9063033a1854a439a7cd0bf6730301c2d2d02ca99a76f098d6e",
|
||||
"/data/digital-drosophila/models/male-cns-lif/phase4l.py": "e97d58d8c1f44920d0e953f8f5831ddc86fa0198784e86460e315de4116ac553",
|
||||
"/data/digital-drosophila/models/male-cns-lif/pn-recruitment-audit-v1/publication.py": "7a79c499098b74163e7bb16adabcbc54e7069dafa204d0b99c7f4c03d79f8016",
|
||||
"/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1/checksums.sha256": "493f541756064d9d65603e550628656a6f2dbf44f8b862ef905e8c3fd2427a43",
|
||||
"/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1/config.json": "c19f00c81f12c4c3503d3d557bd73d0722d4d3fed7279449408c67a89a6ffcf9",
|
||||
"/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1/context.py": "0fa2e0892c973fe70ecbc0613e3cb508c256b7745042f8936edf23dedc31d166",
|
||||
"/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1/eligibility_bridge.py": "174fb8d14619189e74b095e77a6db18b14c93046dc431c0b55710a5aa2dd2e61",
|
||||
"/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1/manifest.json": "7edeb251ecbeac5a64805fefe171a0a0bf8bba2675919ef922cc1a329c203ea8",
|
||||
"/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1/overlay.py": "7f891d0ba79b393c96e75fd2dee2eddc51e57d8213eaac2779703bc2c18712b4",
|
||||
"/tmp/malecns-cpu-residency-woqIQa/inputs/M_D0.authority.json": "56d89454417c4c7d8e4dd1dc3437ad0df55ded706b9e603681bbf491338cbf04",
|
||||
"/tmp/malecns-cpu-residency-woqIQa/inputs/N_D0.authority.json": "4a7ee78ca0671efa0cb5203f7ba405ae3a53b3e23ebfcb8bf52887ce20c0f40b",
|
||||
"/tmp/malecns-cpu-residency-woqIQa/inputs/N_frozen.authority.json": "3063f74a5dbbfb6afa92ee7692bbb0626017b0451072b838be2f9e0bc58748e3"
|
||||
},
|
||||
"max_wall_seconds": 900,
|
||||
"no_automatic_retry": true,
|
||||
"no_brain_execution": true,
|
||||
"no_weight_installation": true,
|
||||
"output_root": "/tmp/malecns-cpu-residency-woqIQa",
|
||||
"prototype_sources": {
|
||||
"/data/digital-drosophila/tools/conditioning-perf-lab-v1/perf_probe.py": "a51e9140e5ddb50211dbeb313d0d546fa583daadecb767c289760f3f4896c2ac",
|
||||
"/data/digital-drosophila/tools/conditioning-perf-lab-v1/resident_validator.py": "dfcea2f1406badc3122c2529e6b905a74e7cdf4e450f86fd82d22a7cb70e5ff7",
|
||||
"/data/digital-drosophila/tools/conditioning-perf-lab-v1/test_perf_probe.py": "d0e24a2dddafd2e96ae57dd4bb71d66809c31099846b9337d9e8e4f30c259f0d"
|
||||
},
|
||||
"schema": "conditioning-cpu-residency-probe-v1",
|
||||
"sequence": [
|
||||
"M",
|
||||
"N",
|
||||
"M",
|
||||
"N_D0",
|
||||
"N_frozen",
|
||||
"M_D0",
|
||||
"M"
|
||||
],
|
||||
"threads": 1
|
||||
}
|
||||
@@ -0,0 +1,292 @@
|
||||
{
|
||||
"checkpoint_dir": "/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/mechanical--fresh-parent",
|
||||
"checkpoint_manifest_sha256": "8814431d9e1afbf431affbe77c7e4402d43b5ece3063cd47696cb77249a295f5",
|
||||
"command": {
|
||||
"compartment": "y5B'2a",
|
||||
"d_command": 0.0,
|
||||
"frozen": false,
|
||||
"steps": 1200,
|
||||
"trace_backend": "torch",
|
||||
"us_tick": 1199
|
||||
},
|
||||
"diagnostic_mode": "reference",
|
||||
"epoch_id": "engineering-residency-control-M_D0",
|
||||
"files": {
|
||||
"am_overlay_source": {
|
||||
"path": "/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1/overlay.py",
|
||||
"sha256": "7f891d0ba79b393c96e75fd2dee2eddc51e57d8213eaac2779703bc2c18712b4"
|
||||
},
|
||||
"base_candidate": {
|
||||
"path": "/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/protocol/base-candidate.float32-mV.npy",
|
||||
"sha256": "1218d1b328f29a7afefb0ca0b7b6421247f14ad598aa1957a6a7aacbc8cebcae"
|
||||
},
|
||||
"candidate_map": {
|
||||
"path": "/data/digital-drosophila/experiments/phase4ao-conditioning-interface/inputs/static/candidate-map.npz",
|
||||
"sha256": "29dcb57fcaefb5817fa4616b9a75285327b41d8a67cfc0f2ad2bacc14e41f2f0"
|
||||
},
|
||||
"canonical_kc": {
|
||||
"path": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/kc_globals.npy",
|
||||
"sha256": "97a570aafa089f93e642b2bb07e3a3322dabb14c3c7dd431f0c8d2b3b7951fdd"
|
||||
},
|
||||
"conditioning_update_source": {
|
||||
"path": "/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/conditioning_update.py",
|
||||
"sha256": "96efff678cff910654eb08e86f1a17789e4e5589e340345f419c7027a7d547e2"
|
||||
},
|
||||
"eligibility_bridge_source": {
|
||||
"path": "/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1/eligibility_bridge.py",
|
||||
"sha256": "174fb8d14619189e74b095e77a6db18b14c93046dc431c0b55710a5aa2dd2e61"
|
||||
},
|
||||
"kc": {
|
||||
"path": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/kc_globals.npy",
|
||||
"sha256": "97a570aafa089f93e642b2bb07e3a3322dabb14c3c7dd431f0c8d2b3b7951fdd"
|
||||
},
|
||||
"mask": {
|
||||
"path": "/data/digital-drosophila/experiments/phase4h-dopamine-plasticity/plastic-mask/plastic-edge-ids.int64.npy",
|
||||
"sha256": "8b0fb6eb2e6c31da4d17dc20d890aa3f367e514f05642de5bad6b42a1611c05b"
|
||||
},
|
||||
"overlay_before": {
|
||||
"path": "/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/overlays/zero.npz",
|
||||
"sha256": "0b219eab09c30dc3af31fef7e6395a9bec1234090abbb72db096da833fed82c5"
|
||||
},
|
||||
"overlay_manifest_before": {
|
||||
"path": "/data/digital-drosophila/experiments/phase4an-engineering-validation/overlays/zero.json",
|
||||
"sha256": "11b668978f3070dad26d99d9310bebefa0731fa0d4e361e8dc0ef02a213277c2"
|
||||
},
|
||||
"phase4j_source": {
|
||||
"path": "/data/digital-drosophila/models/male-cns-lif/mb-physiology-v1/phase4j.py",
|
||||
"sha256": "abb4574da85f00bd9ef61024c65993ef81d42651ff8d8d63c15dd69c6222471e"
|
||||
},
|
||||
"requests": {
|
||||
"path": "/data/digital-drosophila/experiments/phase4aq-conditioning-execution/cases/mechanical--fresh-parent/requests.npz",
|
||||
"sha256": "edabb35c72f41a72cad5965ba0a6789b56c9a4ce38b25d6c6a2811ec3981066b"
|
||||
},
|
||||
"runtime_continuation_source": {
|
||||
"path": "/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/runtime_continuation.py",
|
||||
"sha256": "0b8e8e0a6a23a079dc62a88355ce355d53b3ae22f6665519a8f6aef2dcfc5aba"
|
||||
},
|
||||
"runtime_light_source": {
|
||||
"path": "/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/runtime_light.py",
|
||||
"sha256": "522b8c31ea938890fe15364fccd25ccc5bded54101754909f255532e7ad01aae"
|
||||
},
|
||||
"spec": {
|
||||
"path": "/data/digital-drosophila/experiments/phase4aq-conditioning-execution/cases/mechanical--fresh-parent/spec.json",
|
||||
"sha256": "82d95a9d4f2933986ec30a02cb0a3e1c1b50a0d4eab47068ac1cde169986e57d"
|
||||
},
|
||||
"state": {
|
||||
"path": "/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/mechanical--fresh-parent/state.npz",
|
||||
"sha256": "de5740758c280d250714be96d0598dadf78434ae4b915ff3b6646bbd5219b201"
|
||||
}
|
||||
},
|
||||
"frozen_inputs": {
|
||||
"/data/digital-drosophila/datasets/male-cns-v1.0/processed/neuron-only/neuron-index/unified-metadata.parquet": "922af16846a065c3dbfca7c11146b83ca217fcbd7392edc745f444a04eae8c63",
|
||||
"/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json": "bde79d95ef0097b827d5faf4d5658eafc009d8e9fcef1fddd645c953823e3f64",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/apl_globals.npy": "8388c8795d49cfe5b14fda54f76ef3a35030c62ba87bd8ca6334a2dcdf186f19",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/input_matrix.npy": "c4d3df703ea5f1d7402b8255cfa19d9744139ad1048827c23b151d8ba766fec6",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/kc_globals.npy": "97a570aafa089f93e642b2bb07e3a3322dabb14c3c7dd431f0c8d2b3b7951fdd",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/output_matrix.npy": "e2d0a1ccd740e6777245ebf2efcd88bf5e1da9e47308c63ec8e83d451e134a73",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/dst.npy": "ce20f7433f78442c717ad2a7b5394cf4a3b109d990b4be0788040b7b0f4ed150",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/edge_id.npy": "49260615ff2b6432ce3dea9ce2c7ab8f83d06c2fb7491e58e08355fcedf86a30",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/nodes.npy": "5b511a98e8fbf8d65bbc70b93e75ecae19366f650b7842a45611bfad62ed83dc",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/ptr.npy": "fe43420f11e6242a11f8199ae7f097cab4b8a6db181d36f2a46b9e46670acbb4",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/signed_raw.npy": "f9884ccb8930b32420b27c69271df78034a8350fe5a5c9b76a63c259268efc09",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/src.npy": "bfd625ce690fc21eb0a8b9dede831688ab73b789045ba83ddf4baeefeddf1fc3",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/weights.npy": "462839ffc3feb8f6c278044488082b1c8e410e7f23229d6b5e29d1b7042416a1",
|
||||
"/data/digital-drosophila/experiments/phase4ak-apl-timing-validation/cases/seed_validation/seed_validation-physiological-00-s1073741825/requests.npz": "003a6f6306787b67391735c41dd8b14c689beaaab3ab71a5e9afb376d3cbb091",
|
||||
"/data/digital-drosophila/experiments/phase4ak-apl-timing-validation/cases/seed_validation/seed_validation-physiological-00-s1073741825/spec.json": "ebffa677b41e06cb776a987a496a0577bdda135cf3c067ca8017b038ff3fc5c4",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/audit/final-status.json": "18b12c832e156bd6e5ba950f48a49fb908c62104b91bb3e78213f523c8fdc8f9",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/audit/scientific-summary.json": "03f229fc0768d38bb7c2a3c558dbd68c2c3a622cbf96b1b16aef2819b6b67b77",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/audit/static25-complete.json": "1a9cfd096bfc7ab826e043d450a32403a1a7176ab1f7056a3afaceb5c33ac098",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/audit/zero-complete.json": "59397f4b7874894049cc5e77d0555ddcc8274c9573bc53a4bc5f41429683166e",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/checksums.sha256": "fde235a6d781d4c860107c3aa94671811b3f39b167965034ed57f3278e012c3a",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/adapter-provenance.json": "d1b64bdd7b8bc2023dba8321f74bf8ba0a9cac8ded772711f68efeeeb2297156",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/apl-applied.float32.npy": "6228c9e8ec19cb7532e65728ec8f2bd6b080dca8379b17bd393979beaba4c6eb",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/apl-drive.float32.npy": "19b32ccdefea22ddc3e2efcc98b919b8fcf69887f029c17dc75bafa5b34259c5",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/apl-inhibition.float32.npy": "d5194ea98900ca1800416712619143b731d9b3a5d1391180e6881205c7a4d663",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/apl-pending-tail.float32.npy": "2dd2e0c79d4ee5299b8c1e8863e6c61b81f3dba08e599011887b1e1621f7c945",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/apl-state.float32.npy": "5fe5ac53e012232b42a7e717357e9782b247f74da93640a0cfb8a078bc9d4855",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/apl-timing-audit.json": "6ceacfab219fc40146c3e753bdaa96a9e678762f1aeeec04fa303cbf9ebc09be",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/comparison.json": "becda112d4f7576318e2a825daf8f049eb3916c964252511963779899228974c",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/output-hashes.json": "74748bb4cde4769caa31ecc7c888e9e6192fffc022deee94e4378573d0dbc9cc",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/overlay-audit.json": "949d7f986ae2212d44777bd351b88e54c38db857fc062d4d232c2670d31e3085",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/overlay-input.npz": "7805bd2f86de91777bca86c52870607a2e091ed74b901319b896055ad3463f6d",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/overlay-manifest.json": "96d8406b69e98ba9829a52788c6c96888493e8bf34581d6d653226b1eb2e494b",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/queue.jsonl": "3e93bbae67a18944383b2b11a63708ee31e18b8ae7084f24dcb24045c85aa9a7",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/requests.csv": "b11fb0b6d1ac9211f02f05a9809175c64b72e8bcd4c4e4da31be1efbe6a82a83",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/sealed-gpu-source.diff": "0584f865885b18e6a36870a7ecfbbc98d7a94274fa5e9e073e7cf97597d78a03",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/source-audit.json": "d644f0265632f117bba0e045d26fb266765b1d005a89426b6242f3de034be935",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/state.npz": "7de2f62ecbde41a11db5aa220aed2fa6128e9fb6e65d04357f5373eb21538f81",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/summary.json": "6f6fb3ffc5f9df761a7972aa97444c7c095edb359580d19103044fa54bce674f",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/tick-state-hashes.jsonl": "3428c112a32024b539218aa6f4778cfa8c19c208bbdbfb2567324294370f23ea",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/adapter-provenance.json": "46d8ad74b409145c42f9066f992166f114cef2272bb0c6ea40c58438bdd39c13",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/apl-applied.float32.npy": "b3a535bc095db2464a75560ed11f336a9db8e843c08fd7681a1b9759b624ad8e",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/apl-drive.float32.npy": "8b6432e8947f4c67466b5cae28cb0d0877b61862e80e6d9b10c5734d9afa8411",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/apl-inhibition.float32.npy": "8f9e59026dc7c7663abf8f7abc60ebf93b11a68483bc0960d375a83731acc859",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/apl-pending-tail.float32.npy": "fc1e2d8ffa426d4118a7544129323c5f7523e9df3e298a60922ca0ecabe7c18f",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/apl-state.float32.npy": "36ecfec747be0c700959ba1ac171b81a1f3471aa9baba41b7bb6a67be01213c2",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/apl-timing-audit.json": "850600c0560f98c1f2de35bae506c5619205375e6616137a7e8ff978000b0c3a",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/comparison.json": "3e55e8edaf7e3cf4453e37cf90d7a420808977665174ccf525dfef7553418d46",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/output-hashes.json": "aabd9f46a9697440f0cc0204455e831d16b7aadfdebe3e5a8c986bfe85d05300",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/overlay-audit.json": "22d13f7d6ad27cbe117e01117d46c0457781adf3a0bf2aa6748fe7f4b484aa56",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/overlay-input.npz": "0b219eab09c30dc3af31fef7e6395a9bec1234090abbb72db096da833fed82c5",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/overlay-manifest.json": "902933628aabc9e084b547dfdaff0f8361d353949ba3ee92439a2f35d8625d8a",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/queue.jsonl": "22fbf106279d5ad314beba357137701df111bb28b57accdb09a0e299dfdf39cf",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/requests.csv": "4bcc9ef7fdc596ddac3be3b0d29f0aea2e086deeb803f3a90baba21b5490ef53",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/sealed-gpu-source.diff": "0584f865885b18e6a36870a7ecfbbc98d7a94274fa5e9e073e7cf97597d78a03",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/source-audit.json": "d644f0265632f117bba0e045d26fb266765b1d005a89426b6242f3de034be935",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/state.npz": "933afdc1bd0ea81174aeb334f017cfbe1bbc0a72f8eca767698275c5dca886f3",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/summary.json": "244be6a69b8276a212b1601ab7235e58c0bd9d523c88368025b29f4b4664ddcf",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/tick-state-hashes.jsonl": "0266afe78eadd1ea5bfb25026103d01d2af82d9b6ce2bcbb9d60e576ac898e91",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/manifest.json": "9e24b682935a9b18e05db7a933080c5f63ddbeb8a0c85cc0df1cfe1d06d88ab4",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/overlays/static25.json": "96d8406b69e98ba9829a52788c6c96888493e8bf34581d6d653226b1eb2e494b",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/overlays/static25.npz": "7805bd2f86de91777bca86c52870607a2e091ed74b901319b896055ad3463f6d",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/overlays/zero.json": "902933628aabc9e084b547dfdaff0f8361d353949ba3ee92439a2f35d8625d8a",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/overlays/zero.npz": "0b219eab09c30dc3af31fef7e6395a9bec1234090abbb72db096da833fed82c5",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/protocol/base-candidate.float32-mV.npy": "1218d1b328f29a7afefb0ca0b7b6421247f14ad598aa1957a6a7aacbc8cebcae",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/protocol/prepared-hashes.json": "4af0bccbb9153be0d8cb65c5e4150946be3396ca351eab52b273c86459200580",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/protocol/preregistered.json": "465886b78ada08092c2c83de278844707499718977fb6dc6a7608391da0e5304",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/regression/frozen-five.json": "905c64c8b3f7de942d55f6ecb76c27c42821691a9fd3e0c17ffb466e1de0fea0",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/regression/old-integrity-after.json": "7d3de4ba6248cc52960087bcfa2658f9b8ee34d9ac08c56380f7018c34097929",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/regression/old-integrity-before.json": "7d3de4ba6248cc52960087bcfa2658f9b8ee34d9ac08c56380f7018c34097929",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s00/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s00/template-spec.json": "065e4b01b74ac6619f6533c54fdb58a345fffe7be30ae2295e50ab7015da888a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s01/requests.npz": "929f5b8a23043c0a10790d7cc0683ff81a6049b4e714db86b1fb54cb7f3ca8f2",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s01/template-spec.json": "38001935f07393a08f8c83595541a6ff060b0f9ca7b9fdaf357e2f77f9348994",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s02/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s02/template-spec.json": "c89d7994d40fc79591c78d11c549766b45d283145fdcebb1e3b6c964b8750b2a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s03/requests.npz": "be049a344735ad19157ea86c6e911ea9042127ace736fe98bcdddf6b3c1425d1",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s03/template-spec.json": "390f3d472a2baf3b7d14f1bb22185e027fb1c5ede8f42bfbd8e7c2051e78d0fe",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s04/requests.npz": "764259eb618a2ee9393b67ec2713cd0c68763a3e55bbd35e261f5c38ea044b0e",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s04/template-spec.json": "90a262080e33a6014679e7f3d932f61e1edb04cffcd9a2cf35440c078a9085f4",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s00/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s00/template-spec.json": "3b63e236d755714dc59b083b2ee48761ce48e9a8456770e3502798f5bd5e2ff6",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s01/requests.npz": "929f5b8a23043c0a10790d7cc0683ff81a6049b4e714db86b1fb54cb7f3ca8f2",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s01/template-spec.json": "595a1a67fd82b48e0db25480771a93bd289e8f65c511c43780b42dabf9c8b478",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s02/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s02/template-spec.json": "bda9afb21aebd4cf37d52a0cb83c21f179ca4fe9aca8a43e5a1cc92f2af81897",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s03/requests.npz": "be049a344735ad19157ea86c6e911ea9042127ace736fe98bcdddf6b3c1425d1",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s03/template-spec.json": "246cbb287972c7539c4f53bc2546bd9cdd0dd960e8714bce060db1bee1ba0fc9",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s04/requests.npz": "764259eb618a2ee9393b67ec2713cd0c68763a3e55bbd35e261f5c38ea044b0e",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s04/template-spec.json": "de59abaa0670a9be8d90a9dd9b41522edd277d9f75dbdb77ddeeeca1c508265f",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--fresh--light-r0/requests.npz": "003a6f6306787b67391735c41dd8b14c689beaaab3ab71a5e9afb376d3cbb091",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--fresh--light-r0/template-spec.json": "802b717691f9a6b460a1a58044286e727ffa8393605127ee7a11ad267fbf6338",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--fresh--light-r1/requests.npz": "003a6f6306787b67391735c41dd8b14c689beaaab3ab71a5e9afb376d3cbb091",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--fresh--light-r1/template-spec.json": "f4cdfd5de0fb80dd39203425c4ff7d063b0b66f2ac887e4276043251e3ad956c",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--fresh--reference-r0/requests.npz": "003a6f6306787b67391735c41dd8b14c689beaaab3ab71a5e9afb376d3cbb091",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--fresh--reference-r0/template-spec.json": "2ee541997a8a82f9ac356e9fedf8fc70ce31f622d42d846ab6de8c5f6cdea39f",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--prefix--reference-t0018/requests.npz": "adc91d6f97531e8f94b0bbee6b67b1c62b0303bb90b2ad0aa0adf0af9f990570",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--prefix--reference-t0018/template-spec.json": "282eccfb1ee2008f0b9ae8cca4daf45bfefd664806e7d04b8712fadf90b83bb5",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--prefix--reference-t0019/requests.npz": "adc91d6f97531e8f94b0bbee6b67b1c62b0303bb90b2ad0aa0adf0af9f990570",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--prefix--reference-t0019/template-spec.json": "8cd7512a1b2cdef47aecfd26bfb7ee8b22b566dc6c6812e887b4cc3f5416e7e3",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--prefix--reference-t0500/requests.npz": "aa2773a740b0e85940f3d96738a141903d5d178e40586522b603ae1c9de53e98",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--prefix--reference-t0500/template-spec.json": "654043502385a40dc4396c25ab2bf6f74701a7026fc85e6789672a810e5f700e",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s00/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s00/template-spec.json": "e8f6fe8e0f67cbe851c045a067485d753979f5af32d30f596f545387b306f123",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s01/requests.npz": "929f5b8a23043c0a10790d7cc0683ff81a6049b4e714db86b1fb54cb7f3ca8f2",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s01/template-spec.json": "b727d54f9d28e9b8482860c3ed2bb6c30d4778fe90644b2df9ebb8d0c032e148",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s02/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s02/template-spec.json": "8af5bc5ed35084f15c7d77ded8224d49f49561d48510c862410eccd4d7dc5560",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s03/requests.npz": "be049a344735ad19157ea86c6e911ea9042127ace736fe98bcdddf6b3c1425d1",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s03/template-spec.json": "7e140b41ae610cd67a8cfe2e30d633190ac2c7689a4682bba676e423b54e689d",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s04/requests.npz": "764259eb618a2ee9393b67ec2713cd0c68763a3e55bbd35e261f5c38ea044b0e",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s04/template-spec.json": "5cc7905cdca67bdf09eb0730a274644f5605178b1c97928572c5ecf2a3b5acff",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s00/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s00/template-spec.json": "452da911a5f3d6d8cbd33e96451d6f65af5e46eee57fda00125c59f6378dfba6",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s01/requests.npz": "929f5b8a23043c0a10790d7cc0683ff81a6049b4e714db86b1fb54cb7f3ca8f2",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s01/template-spec.json": "b943e29941af75b7c4ff333bdc0a9697d0e15131bdea46c4460ef91f894565b2",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s02/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s02/template-spec.json": "412390b67001e08930f243f54954d78e7edf94b330aee2087c35748963a883db",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s03/requests.npz": "be049a344735ad19157ea86c6e911ea9042127ace736fe98bcdddf6b3c1425d1",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s03/template-spec.json": "6d5f2819be44646890cdad1969043bee5209e801b79687a8c1c2205601bc9656",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s04/requests.npz": "764259eb618a2ee9393b67ec2713cd0c68763a3e55bbd35e261f5c38ea044b0e",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s04/template-spec.json": "d8bd2b1b151582ec7495e59a15cae15279f71d444429c5c273397b63008b3440",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--fresh--light-r0/requests.npz": "003a6f6306787b67391735c41dd8b14c689beaaab3ab71a5e9afb376d3cbb091",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--fresh--light-r0/template-spec.json": "df1a6663ea748b0dc0333540877000e5c91d493b151e134e346dee54e834e3de",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--fresh--light-r1/requests.npz": "003a6f6306787b67391735c41dd8b14c689beaaab3ab71a5e9afb376d3cbb091",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--fresh--light-r1/template-spec.json": "32dce4105aaadac4f7079264cf0a30a3f8171862edf59cceaba6624f01a5252d",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--fresh--reference-r0/requests.npz": "003a6f6306787b67391735c41dd8b14c689beaaab3ab71a5e9afb376d3cbb091",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--fresh--reference-r0/template-spec.json": "a0bf214d782ddef0adb5b6f9b89c2d52566a5928b5d96316bddfe12520aa5460",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--prefix--reference-t0018/requests.npz": "adc91d6f97531e8f94b0bbee6b67b1c62b0303bb90b2ad0aa0adf0af9f990570",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--prefix--reference-t0018/template-spec.json": "8400934e175d3c20f19d863082e7df02c5279864b5191736565e9014df6e0e83",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--prefix--reference-t0019/requests.npz": "adc91d6f97531e8f94b0bbee6b67b1c62b0303bb90b2ad0aa0adf0af9f990570",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--prefix--reference-t0019/template-spec.json": "9c361dfb9af4dd7071a7f1c3c2315adddb21b42e9ed5e9a199b1cdf52fab40e7",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--prefix--reference-t0500/requests.npz": "aa2773a740b0e85940f3d96738a141903d5d178e40586522b603ae1c9de53e98",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--prefix--reference-t0500/template-spec.json": "bda640a599d6cdf80ad435f344fcd576d91ca0afe9de732f36fa7bd54d470c1e",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/overlays/static25.json": "b0ee003192fbdfd869f8b23c9bbab0ff99079b7bd2bf1dc33b7afef40785a143",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/overlays/zero.json": "11b668978f3070dad26d99d9310bebefa0731fa0d4e361e8dc0ef02a213277c2",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/AM-gate-authority.json": "66257eb665808e33005dd7ba14a16063064618cc48e47cb65b70f3900cec2484",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/AM-seal-verification.json": "175b5d0e2de12a9ce01c6167591dab882d9c9c6869de2d194bcd9e6732c6ed6d",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/ENGINEERING_GATE_DRAFT.md": "1ac0d65b906e1061781c967cc6a99e8a0a73df6a1ee564ed6603f88e3f5d7056",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_analysis.py": "3970d13bd43d4bc12baf4b6ad1cda3eb085e10bf4648752cfcecb6d12314c5ea",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_compare.py": "5a2403f11bc08d65a9d242ac2cf9686b850e0c3680d65659f785e9b6b50c0238",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_inputs.py": "cc8c0e83016af4836c81cd0773fc521c69fd30e6f4d021bf54d0e7897105c6d5",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_plan.py": "3c127aee723a054fda272fee458067608b521a7c443455822d97f509caded6c7",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_prepare.py": "62dedce2439407398e70beb4c718bf14e02d3e624b3db3ef6f74299115d84bc1",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_queue_audit.py": "6ddaec52f2a0b5d0c528d51230d372fe2344160aef5eccea6a95b6c5e61a574e",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_scopes.py": "1043ba217e5395c9e81e58b95a5aa396f572588872b954e549774f2b99cac5df",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_workflow.py": "76313332b8d18f121a61f7b6e2fc32ea9e893848e8ed5d049557fc08b385e674",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/runtime_continuation.py": "0b8e8e0a6a23a079dc62a88355ce355d53b3ae22f6665519a8f6aef2dcfc5aba",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/runtime_light.py": "522b8c31ea938890fe15364fccd25ccc5bded54101754909f255532e7ad01aae",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_analysis.py": "35e4ee37a1e82cf5e645d24165343049d400104c94a6d184b8aa834ba5ef2d20",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_compare.py": "87a85843d918cce6529ab94f7cb82499aa413281e803c00c030a3c340a581469",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_inputs.py": "4dcc7b775eb3c7e59ed9cc3d7591eacc0ef7bda1209edbd847e2ae79b115ef1b",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_plan.py": "c26c2c75bb27d3b8514b7d44f40369130d60147c6c8edc569b4efba4a4ad9815",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_prepare.py": "a12aa1d2cb4880a3f7a7889b89d71a859bc8c68b4badfb8f082d712cdd342627",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_queue_audit.py": "0e2bcfe25c3b5a5cd0ed5cd05a89392207191ec4db950cdb06a0137666c8adb7",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_scopes.py": "748c0777e4a8164e80c03c727df1c2decbac7747737ad1c9fb730ea5c9e208d3",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_workflow.py": "bb781b23f92b5c0eb92f8dbc54468a8e843177f6da004c444b48947b037bd705",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_runtime_continuation.py": "325c0b688d0ca1648ffdf29a8d3d4bb91d6f6115bea6f5ac30982acd6dfe8e06",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_runtime_light.py": "887345e497e6fa9c10ffa49c490196711d8cee028c62ec7a73f42db36569be2b",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/regression/old-integrity-before.json": "68475cc0e72039e044c8fb3aaea9c8487c6737c1b8a457641e818581d81c387c",
|
||||
"/data/digital-drosophila/experiments/phase4h-dopamine-plasticity/mappings/dan-to-compartment.parquet": "a16f72c3121ed0ec638c1a2b249ace446e6ccee020b49679818eb42589d00662",
|
||||
"/data/digital-drosophila/experiments/phase4h-dopamine-plasticity/mappings/dan-to-mbon-confirmed.parquet": "730d000f25667b59181d2ee6703c64591229a8beab0856197ed71e68d799d191",
|
||||
"/data/digital-drosophila/experiments/phase4h-dopamine-plasticity/mappings/mbon-to-compartment.parquet": "54f371f7e35b9def44becd1ba9bd2872861f4876b255b2c8ec46feee6473b70c",
|
||||
"/data/digital-drosophila/experiments/phase4h-dopamine-plasticity/plastic-mask/plastic-edge-candidates.parquet": "e5075ee3e5a0edf3a4d197453847163cc295b254f21c67203159bba204b12a76",
|
||||
"/data/digital-drosophila/experiments/phase4h-dopamine-plasticity/plastic-mask/plastic-edge-ids.int64.npy": "8b0fb6eb2e6c31da4d17dc20d890aa3f367e514f05642de5bad6b42a1611c05b",
|
||||
"/data/digital-drosophila/experiments/phase4l-olfactory-grounding/odor-encoder/frozen-odor-panel.parquet": "907f16a56e024a8e2112b5751e53b0e6037b329fa110098af3d31b119c10a1a0",
|
||||
"/data/digital-drosophila/experiments/phase4l-olfactory-grounding/odor-encoder/mapped-glomerular-vectors.npz": "f057563152e0fa22060080af13019f319e7f36563a775eff829bbc1929c451b0",
|
||||
"/data/digital-drosophila/experiments/phase4l-olfactory-grounding/odor-encoder/selection.json": "1b832becf9d08935716fe9ba5e3cd3e619e7d208dfb43c4fa197c969d095f113",
|
||||
"/data/digital-drosophila/experiments/phase4l-olfactory-grounding/receptor-mapping/olfactory-mapping.parquet": "a01d27000533e9844458a4c559cac084f1c34ca20a1104e97e6a0f72b0cc93b1",
|
||||
"/data/digital-drosophila/models/male-cns-lif/apl-timing-lab-v1/gpu_timing.py": "af1975ba5e5e700208c0a598d3cbe648a3cf10885c6231239b6e4b28f76d173b",
|
||||
"/data/digital-drosophila/models/male-cns-lif/apl-timing-lab-v1/timing_queue.py": "54df6d4818e2a0c26e96fb0aaf5d9b71cd964981706da937562d48af79aca14e",
|
||||
"/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/gpu_apl.py": "69f5d893f47dafff4ef7c3186c3df0b9014666b32c8f4e943b57016bec92b18a",
|
||||
"/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/legacy_apl_worker.py": "21ceec65fe42581dc55872010e0025d660e80358905f1cf4df1dadf341a3b291",
|
||||
"/data/digital-drosophila/models/male-cns-lif/author-fullgraph-lab-v1/oracle_full.py": "d72003d98f0f1624b12126eff50bd361c43d888f4a64d90ba9247a58976f1961",
|
||||
"/data/digital-drosophila/models/male-cns-lif/author-runtime-lab-v1/author_ext.cpp": "208a937d17bbb041b9bf6b25b89264ee566830b60609e58491b44583d8541f15",
|
||||
"/data/digital-drosophila/models/male-cns-lif/author-runtime-lab-v1/author_ext.cu": "669f166e18ce9a3f63fc723db8b0a8b74f7fa4757194b1bd65b4cf6008a7787e",
|
||||
"/data/digital-drosophila/models/male-cns-lif/author-runtime-lab-v1/gpu_backend.py": "03758d07572f4b44d272059d9308fac534268ad201b57bdd77d69fee95e67278",
|
||||
"/data/digital-drosophila/models/male-cns-lif/mb-physiology-v1/phase4j.py": "abb4574da85f00bd9ef61024c65993ef81d42651ff8d8d63c15dd69c6222471e",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/EVALUATION_POLICY_DRAFT.md": "a84170a61564715a1532f20df4c6a330f0f9725c383db48b8f3e1a4b5fba0bc8",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/EVIDENCE_DRAFT.md": "8455c12e3a6bb1b22a6e38f9017293fe5deea37ba3ec61e13598d00dafc12296",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/PROTOCOL_DRAFT.md": "8ebecb1f3d012ddc29a1cb727269dd277629c53565e09978bf9dbf7140cb8508",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/README_DRAFT.md": "50be97f64097b681355993a8afd7f467ea187e99e88b19ca30561e08d517999f",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/biological_contract.py": "e09f0f2b5e6ec746176e3a1aa2fdee1a15385e14e96bd343d14379a759f3ae43",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/conditioning_inputs.py": "19382e066e450140bb653a3661f980ffe7cc62f412020ef57df0b6e6b3cbb8ba",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/conditioning_update.py": "96efff678cff910654eb08e86f1a17789e4e5589e340345f419c7027a7d547e2",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/draft-source-inventory.json": "2c72d47d09b4ad1949dc6cfdc170f64847ff75f95ded5d20b421fb5a75e0eb84",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/evaluation_plan.py": "991c813ff3322b230947f302b12b04ec382c3b632817f94b698101e4b17efa7d",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/evaluation_policy.py": "21331a9ff3567dc6f6399e16bb91ef486d74231f5db51799beb6dd1bf71d022b",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/metrics.py": "47319e21db3c8b030b1bafbf0703cd86fb588d23bb29436accbacdba73d08c3c",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/seed_registry.py": "0da033b132095ec3087b5d9f64e53c2e391fa50ab0b7653b31296eeb84799b7e",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_biological_contract.py": "0ce796e6ad1a4cbcb9bcb760eff628a9562b4a809cc9c177a9a0d88df68f02b3",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_conditioning_inputs.py": "95e37c770e78ce722a3007c5b371c51aec2989634cddfe5b414ac3fa817e5c22",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_conditioning_update.py": "1c25d93753932ace06abc876fe0867546b3bb330de3e602da6aec7bb4588e4bd",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_evaluation_plan.py": "21d2402025122d8665fb1f32e184fd8e30fc17242810fc70901b7f7fc8c53bfa",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_evaluation_policy.py": "421a31b76eaa547e890c291d2c38a415352d9ccad6fccc800461f522ff4c83f1",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_metrics.py": "1928894d248dd37fad0fc67bc9dcfeac27c4d8be4aec22f54b9ef20a10ea8645",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_seed_registry.py": "7aca38f3c975e3ad4f6337d83b826c09afef336381d124c22ff0eb2eb60a0834",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_trial_plan.py": "927678956ae9959a047b1cd258ee8dee22eb6842a96ff4b2ba2db077310163c9",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/trial_plan.py": "6fed3f494d075339a7e5b001d43b2598640b189e038952fbd4d41200bacac587",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-grounding-v1/phase4l.yaml": "9b8bcb7e031bf9063033a1854a439a7cd0bf6730301c2d2d02ca99a76f098d6e",
|
||||
"/data/digital-drosophila/models/male-cns-lif/phase4l.py": "e97d58d8c1f44920d0e953f8f5831ddc86fa0198784e86460e315de4116ac553",
|
||||
"/data/digital-drosophila/models/male-cns-lif/pn-recruitment-audit-v1/publication.py": "7a79c499098b74163e7bb16adabcbc54e7069dafa204d0b99c7f4c03d79f8016",
|
||||
"/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1/checksums.sha256": "493f541756064d9d65603e550628656a6f2dbf44f8b862ef905e8c3fd2427a43",
|
||||
"/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1/config.json": "c19f00c81f12c4c3503d3d557bd73d0722d4d3fed7279449408c67a89a6ffcf9",
|
||||
"/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1/context.py": "0fa2e0892c973fe70ecbc0613e3cb508c256b7745042f8936edf23dedc31d166",
|
||||
"/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1/eligibility_bridge.py": "174fb8d14619189e74b095e77a6db18b14c93046dc431c0b55710a5aa2dd2e61",
|
||||
"/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1/manifest.json": "7edeb251ecbeac5a64805fefe171a0a0bf8bba2675919ef922cc1a329c203ea8",
|
||||
"/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1/overlay.py": "7f891d0ba79b393c96e75fd2dee2eddc51e57d8213eaac2779703bc2c18712b4"
|
||||
},
|
||||
"schema": "phase4an-epoch-postprocess-authority-v1"
|
||||
}
|
||||
@@ -0,0 +1,292 @@
|
||||
{
|
||||
"checkpoint_dir": "/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/performance--natural-light-fresh",
|
||||
"checkpoint_manifest_sha256": "5cec0f224be49493af884e969cb97d47ac3e000da88c6d0ac8d1b23e3025db8a",
|
||||
"command": {
|
||||
"compartment": "y5B'2a",
|
||||
"d_command": 0.0,
|
||||
"frozen": false,
|
||||
"steps": 1200,
|
||||
"trace_backend": "torch",
|
||||
"us_tick": 900
|
||||
},
|
||||
"diagnostic_mode": "light",
|
||||
"epoch_id": "engineering-residency-control-N_D0",
|
||||
"files": {
|
||||
"am_overlay_source": {
|
||||
"path": "/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1/overlay.py",
|
||||
"sha256": "7f891d0ba79b393c96e75fd2dee2eddc51e57d8213eaac2779703bc2c18712b4"
|
||||
},
|
||||
"base_candidate": {
|
||||
"path": "/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/protocol/base-candidate.float32-mV.npy",
|
||||
"sha256": "1218d1b328f29a7afefb0ca0b7b6421247f14ad598aa1957a6a7aacbc8cebcae"
|
||||
},
|
||||
"candidate_map": {
|
||||
"path": "/data/digital-drosophila/experiments/phase4ao-conditioning-interface/inputs/static/candidate-map.npz",
|
||||
"sha256": "29dcb57fcaefb5817fa4616b9a75285327b41d8a67cfc0f2ad2bacc14e41f2f0"
|
||||
},
|
||||
"canonical_kc": {
|
||||
"path": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/kc_globals.npy",
|
||||
"sha256": "97a570aafa089f93e642b2bb07e3a3322dabb14c3c7dd431f0c8d2b3b7951fdd"
|
||||
},
|
||||
"conditioning_update_source": {
|
||||
"path": "/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/conditioning_update.py",
|
||||
"sha256": "96efff678cff910654eb08e86f1a17789e4e5589e340345f419c7027a7d547e2"
|
||||
},
|
||||
"eligibility_bridge_source": {
|
||||
"path": "/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1/eligibility_bridge.py",
|
||||
"sha256": "174fb8d14619189e74b095e77a6db18b14c93046dc431c0b55710a5aa2dd2e61"
|
||||
},
|
||||
"kc": {
|
||||
"path": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/kc_globals.npy",
|
||||
"sha256": "97a570aafa089f93e642b2bb07e3a3322dabb14c3c7dd431f0c8d2b3b7951fdd"
|
||||
},
|
||||
"mask": {
|
||||
"path": "/data/digital-drosophila/experiments/phase4h-dopamine-plasticity/plastic-mask/plastic-edge-ids.int64.npy",
|
||||
"sha256": "8b0fb6eb2e6c31da4d17dc20d890aa3f367e514f05642de5bad6b42a1611c05b"
|
||||
},
|
||||
"overlay_before": {
|
||||
"path": "/data/digital-drosophila/experiments/phase4ap-conditioning-interface-v2/updates/D1--reference--epoch-000/delta-after.npz",
|
||||
"sha256": "b89e407a5d93b5f1901f901b00428dc19bd20cee2d81e57b117a2fa68d200a48"
|
||||
},
|
||||
"overlay_manifest_before": {
|
||||
"path": "/data/digital-drosophila/experiments/phase4ap-conditioning-interface-v2/updates/D1--reference--epoch-000/overlay-manifest.json",
|
||||
"sha256": "38dabc55ea0569843ee70f13cf570832ecaa8f1ee7f26a7420e7ebc3ea86f6bd"
|
||||
},
|
||||
"phase4j_source": {
|
||||
"path": "/data/digital-drosophila/models/male-cns-lif/mb-physiology-v1/phase4j.py",
|
||||
"sha256": "abb4574da85f00bd9ef61024c65993ef81d42651ff8d8d63c15dd69c6222471e"
|
||||
},
|
||||
"requests": {
|
||||
"path": "/data/digital-drosophila/experiments/phase4aq-conditioning-execution/cases/performance--natural-light-fresh/requests.npz",
|
||||
"sha256": "571d09c32cabd45af79f71f0f27f7adcc38b9c65daf5ca124366ea439e088143"
|
||||
},
|
||||
"runtime_continuation_source": {
|
||||
"path": "/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/runtime_continuation.py",
|
||||
"sha256": "0b8e8e0a6a23a079dc62a88355ce355d53b3ae22f6665519a8f6aef2dcfc5aba"
|
||||
},
|
||||
"runtime_light_source": {
|
||||
"path": "/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/runtime_light.py",
|
||||
"sha256": "522b8c31ea938890fe15364fccd25ccc5bded54101754909f255532e7ad01aae"
|
||||
},
|
||||
"spec": {
|
||||
"path": "/data/digital-drosophila/experiments/phase4aq-conditioning-execution/cases/performance--natural-light-fresh/spec.json",
|
||||
"sha256": "ea4c40897aceb26edfa5db934647fbc6f6946746441f843bc336f15e5d4e0a23"
|
||||
},
|
||||
"state": {
|
||||
"path": "/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/performance--natural-light-fresh/state.npz",
|
||||
"sha256": "137d5a73a869f27df8a3f97002ca6a683c80d3d715057759fb2aad64a05d37ff"
|
||||
}
|
||||
},
|
||||
"frozen_inputs": {
|
||||
"/data/digital-drosophila/datasets/male-cns-v1.0/processed/neuron-only/neuron-index/unified-metadata.parquet": "922af16846a065c3dbfca7c11146b83ca217fcbd7392edc745f444a04eae8c63",
|
||||
"/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json": "bde79d95ef0097b827d5faf4d5658eafc009d8e9fcef1fddd645c953823e3f64",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/apl_globals.npy": "8388c8795d49cfe5b14fda54f76ef3a35030c62ba87bd8ca6334a2dcdf186f19",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/input_matrix.npy": "c4d3df703ea5f1d7402b8255cfa19d9744139ad1048827c23b151d8ba766fec6",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/kc_globals.npy": "97a570aafa089f93e642b2bb07e3a3322dabb14c3c7dd431f0c8d2b3b7951fdd",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/output_matrix.npy": "e2d0a1ccd740e6777245ebf2efcd88bf5e1da9e47308c63ec8e83d451e134a73",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/dst.npy": "ce20f7433f78442c717ad2a7b5394cf4a3b109d990b4be0788040b7b0f4ed150",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/edge_id.npy": "49260615ff2b6432ce3dea9ce2c7ab8f83d06c2fb7491e58e08355fcedf86a30",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/nodes.npy": "5b511a98e8fbf8d65bbc70b93e75ecae19366f650b7842a45611bfad62ed83dc",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/ptr.npy": "fe43420f11e6242a11f8199ae7f097cab4b8a6db181d36f2a46b9e46670acbb4",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/signed_raw.npy": "f9884ccb8930b32420b27c69271df78034a8350fe5a5c9b76a63c259268efc09",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/src.npy": "bfd625ce690fc21eb0a8b9dede831688ab73b789045ba83ddf4baeefeddf1fc3",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/weights.npy": "462839ffc3feb8f6c278044488082b1c8e410e7f23229d6b5e29d1b7042416a1",
|
||||
"/data/digital-drosophila/experiments/phase4ak-apl-timing-validation/cases/seed_validation/seed_validation-physiological-00-s1073741825/requests.npz": "003a6f6306787b67391735c41dd8b14c689beaaab3ab71a5e9afb376d3cbb091",
|
||||
"/data/digital-drosophila/experiments/phase4ak-apl-timing-validation/cases/seed_validation/seed_validation-physiological-00-s1073741825/spec.json": "ebffa677b41e06cb776a987a496a0577bdda135cf3c067ca8017b038ff3fc5c4",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/audit/final-status.json": "18b12c832e156bd6e5ba950f48a49fb908c62104b91bb3e78213f523c8fdc8f9",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/audit/scientific-summary.json": "03f229fc0768d38bb7c2a3c558dbd68c2c3a622cbf96b1b16aef2819b6b67b77",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/audit/static25-complete.json": "1a9cfd096bfc7ab826e043d450a32403a1a7176ab1f7056a3afaceb5c33ac098",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/audit/zero-complete.json": "59397f4b7874894049cc5e77d0555ddcc8274c9573bc53a4bc5f41429683166e",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/checksums.sha256": "fde235a6d781d4c860107c3aa94671811b3f39b167965034ed57f3278e012c3a",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/adapter-provenance.json": "d1b64bdd7b8bc2023dba8321f74bf8ba0a9cac8ded772711f68efeeeb2297156",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/apl-applied.float32.npy": "6228c9e8ec19cb7532e65728ec8f2bd6b080dca8379b17bd393979beaba4c6eb",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/apl-drive.float32.npy": "19b32ccdefea22ddc3e2efcc98b919b8fcf69887f029c17dc75bafa5b34259c5",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/apl-inhibition.float32.npy": "d5194ea98900ca1800416712619143b731d9b3a5d1391180e6881205c7a4d663",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/apl-pending-tail.float32.npy": "2dd2e0c79d4ee5299b8c1e8863e6c61b81f3dba08e599011887b1e1621f7c945",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/apl-state.float32.npy": "5fe5ac53e012232b42a7e717357e9782b247f74da93640a0cfb8a078bc9d4855",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/apl-timing-audit.json": "6ceacfab219fc40146c3e753bdaa96a9e678762f1aeeec04fa303cbf9ebc09be",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/comparison.json": "becda112d4f7576318e2a825daf8f049eb3916c964252511963779899228974c",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/output-hashes.json": "74748bb4cde4769caa31ecc7c888e9e6192fffc022deee94e4378573d0dbc9cc",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/overlay-audit.json": "949d7f986ae2212d44777bd351b88e54c38db857fc062d4d232c2670d31e3085",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/overlay-input.npz": "7805bd2f86de91777bca86c52870607a2e091ed74b901319b896055ad3463f6d",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/overlay-manifest.json": "96d8406b69e98ba9829a52788c6c96888493e8bf34581d6d653226b1eb2e494b",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/queue.jsonl": "3e93bbae67a18944383b2b11a63708ee31e18b8ae7084f24dcb24045c85aa9a7",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/requests.csv": "b11fb0b6d1ac9211f02f05a9809175c64b72e8bcd4c4e4da31be1efbe6a82a83",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/sealed-gpu-source.diff": "0584f865885b18e6a36870a7ecfbbc98d7a94274fa5e9e073e7cf97597d78a03",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/source-audit.json": "d644f0265632f117bba0e045d26fb266765b1d005a89426b6242f3de034be935",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/state.npz": "7de2f62ecbde41a11db5aa220aed2fa6128e9fb6e65d04357f5373eb21538f81",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/summary.json": "6f6fb3ffc5f9df761a7972aa97444c7c095edb359580d19103044fa54bce674f",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/tick-state-hashes.jsonl": "3428c112a32024b539218aa6f4778cfa8c19c208bbdbfb2567324294370f23ea",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/adapter-provenance.json": "46d8ad74b409145c42f9066f992166f114cef2272bb0c6ea40c58438bdd39c13",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/apl-applied.float32.npy": "b3a535bc095db2464a75560ed11f336a9db8e843c08fd7681a1b9759b624ad8e",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/apl-drive.float32.npy": "8b6432e8947f4c67466b5cae28cb0d0877b61862e80e6d9b10c5734d9afa8411",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/apl-inhibition.float32.npy": "8f9e59026dc7c7663abf8f7abc60ebf93b11a68483bc0960d375a83731acc859",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/apl-pending-tail.float32.npy": "fc1e2d8ffa426d4118a7544129323c5f7523e9df3e298a60922ca0ecabe7c18f",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/apl-state.float32.npy": "36ecfec747be0c700959ba1ac171b81a1f3471aa9baba41b7bb6a67be01213c2",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/apl-timing-audit.json": "850600c0560f98c1f2de35bae506c5619205375e6616137a7e8ff978000b0c3a",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/comparison.json": "3e55e8edaf7e3cf4453e37cf90d7a420808977665174ccf525dfef7553418d46",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/output-hashes.json": "aabd9f46a9697440f0cc0204455e831d16b7aadfdebe3e5a8c986bfe85d05300",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/overlay-audit.json": "22d13f7d6ad27cbe117e01117d46c0457781adf3a0bf2aa6748fe7f4b484aa56",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/overlay-input.npz": "0b219eab09c30dc3af31fef7e6395a9bec1234090abbb72db096da833fed82c5",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/overlay-manifest.json": "902933628aabc9e084b547dfdaff0f8361d353949ba3ee92439a2f35d8625d8a",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/queue.jsonl": "22fbf106279d5ad314beba357137701df111bb28b57accdb09a0e299dfdf39cf",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/requests.csv": "4bcc9ef7fdc596ddac3be3b0d29f0aea2e086deeb803f3a90baba21b5490ef53",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/sealed-gpu-source.diff": "0584f865885b18e6a36870a7ecfbbc98d7a94274fa5e9e073e7cf97597d78a03",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/source-audit.json": "d644f0265632f117bba0e045d26fb266765b1d005a89426b6242f3de034be935",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/state.npz": "933afdc1bd0ea81174aeb334f017cfbe1bbc0a72f8eca767698275c5dca886f3",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/summary.json": "244be6a69b8276a212b1601ab7235e58c0bd9d523c88368025b29f4b4664ddcf",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/tick-state-hashes.jsonl": "0266afe78eadd1ea5bfb25026103d01d2af82d9b6ce2bcbb9d60e576ac898e91",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/manifest.json": "9e24b682935a9b18e05db7a933080c5f63ddbeb8a0c85cc0df1cfe1d06d88ab4",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/overlays/static25.json": "96d8406b69e98ba9829a52788c6c96888493e8bf34581d6d653226b1eb2e494b",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/overlays/static25.npz": "7805bd2f86de91777bca86c52870607a2e091ed74b901319b896055ad3463f6d",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/overlays/zero.json": "902933628aabc9e084b547dfdaff0f8361d353949ba3ee92439a2f35d8625d8a",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/overlays/zero.npz": "0b219eab09c30dc3af31fef7e6395a9bec1234090abbb72db096da833fed82c5",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/protocol/base-candidate.float32-mV.npy": "1218d1b328f29a7afefb0ca0b7b6421247f14ad598aa1957a6a7aacbc8cebcae",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/protocol/prepared-hashes.json": "4af0bccbb9153be0d8cb65c5e4150946be3396ca351eab52b273c86459200580",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/protocol/preregistered.json": "465886b78ada08092c2c83de278844707499718977fb6dc6a7608391da0e5304",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/regression/frozen-five.json": "905c64c8b3f7de942d55f6ecb76c27c42821691a9fd3e0c17ffb466e1de0fea0",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/regression/old-integrity-after.json": "7d3de4ba6248cc52960087bcfa2658f9b8ee34d9ac08c56380f7018c34097929",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/regression/old-integrity-before.json": "7d3de4ba6248cc52960087bcfa2658f9b8ee34d9ac08c56380f7018c34097929",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s00/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s00/template-spec.json": "065e4b01b74ac6619f6533c54fdb58a345fffe7be30ae2295e50ab7015da888a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s01/requests.npz": "929f5b8a23043c0a10790d7cc0683ff81a6049b4e714db86b1fb54cb7f3ca8f2",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s01/template-spec.json": "38001935f07393a08f8c83595541a6ff060b0f9ca7b9fdaf357e2f77f9348994",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s02/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s02/template-spec.json": "c89d7994d40fc79591c78d11c549766b45d283145fdcebb1e3b6c964b8750b2a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s03/requests.npz": "be049a344735ad19157ea86c6e911ea9042127ace736fe98bcdddf6b3c1425d1",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s03/template-spec.json": "390f3d472a2baf3b7d14f1bb22185e027fb1c5ede8f42bfbd8e7c2051e78d0fe",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s04/requests.npz": "764259eb618a2ee9393b67ec2713cd0c68763a3e55bbd35e261f5c38ea044b0e",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s04/template-spec.json": "90a262080e33a6014679e7f3d932f61e1edb04cffcd9a2cf35440c078a9085f4",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s00/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s00/template-spec.json": "3b63e236d755714dc59b083b2ee48761ce48e9a8456770e3502798f5bd5e2ff6",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s01/requests.npz": "929f5b8a23043c0a10790d7cc0683ff81a6049b4e714db86b1fb54cb7f3ca8f2",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s01/template-spec.json": "595a1a67fd82b48e0db25480771a93bd289e8f65c511c43780b42dabf9c8b478",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s02/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s02/template-spec.json": "bda9afb21aebd4cf37d52a0cb83c21f179ca4fe9aca8a43e5a1cc92f2af81897",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s03/requests.npz": "be049a344735ad19157ea86c6e911ea9042127ace736fe98bcdddf6b3c1425d1",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s03/template-spec.json": "246cbb287972c7539c4f53bc2546bd9cdd0dd960e8714bce060db1bee1ba0fc9",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s04/requests.npz": "764259eb618a2ee9393b67ec2713cd0c68763a3e55bbd35e261f5c38ea044b0e",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s04/template-spec.json": "de59abaa0670a9be8d90a9dd9b41522edd277d9f75dbdb77ddeeeca1c508265f",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--fresh--light-r0/requests.npz": "003a6f6306787b67391735c41dd8b14c689beaaab3ab71a5e9afb376d3cbb091",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--fresh--light-r0/template-spec.json": "802b717691f9a6b460a1a58044286e727ffa8393605127ee7a11ad267fbf6338",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--fresh--light-r1/requests.npz": "003a6f6306787b67391735c41dd8b14c689beaaab3ab71a5e9afb376d3cbb091",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--fresh--light-r1/template-spec.json": "f4cdfd5de0fb80dd39203425c4ff7d063b0b66f2ac887e4276043251e3ad956c",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--fresh--reference-r0/requests.npz": "003a6f6306787b67391735c41dd8b14c689beaaab3ab71a5e9afb376d3cbb091",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--fresh--reference-r0/template-spec.json": "2ee541997a8a82f9ac356e9fedf8fc70ce31f622d42d846ab6de8c5f6cdea39f",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--prefix--reference-t0018/requests.npz": "adc91d6f97531e8f94b0bbee6b67b1c62b0303bb90b2ad0aa0adf0af9f990570",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--prefix--reference-t0018/template-spec.json": "282eccfb1ee2008f0b9ae8cca4daf45bfefd664806e7d04b8712fadf90b83bb5",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--prefix--reference-t0019/requests.npz": "adc91d6f97531e8f94b0bbee6b67b1c62b0303bb90b2ad0aa0adf0af9f990570",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--prefix--reference-t0019/template-spec.json": "8cd7512a1b2cdef47aecfd26bfb7ee8b22b566dc6c6812e887b4cc3f5416e7e3",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--prefix--reference-t0500/requests.npz": "aa2773a740b0e85940f3d96738a141903d5d178e40586522b603ae1c9de53e98",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--prefix--reference-t0500/template-spec.json": "654043502385a40dc4396c25ab2bf6f74701a7026fc85e6789672a810e5f700e",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s00/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s00/template-spec.json": "e8f6fe8e0f67cbe851c045a067485d753979f5af32d30f596f545387b306f123",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s01/requests.npz": "929f5b8a23043c0a10790d7cc0683ff81a6049b4e714db86b1fb54cb7f3ca8f2",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s01/template-spec.json": "b727d54f9d28e9b8482860c3ed2bb6c30d4778fe90644b2df9ebb8d0c032e148",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s02/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s02/template-spec.json": "8af5bc5ed35084f15c7d77ded8224d49f49561d48510c862410eccd4d7dc5560",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s03/requests.npz": "be049a344735ad19157ea86c6e911ea9042127ace736fe98bcdddf6b3c1425d1",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s03/template-spec.json": "7e140b41ae610cd67a8cfe2e30d633190ac2c7689a4682bba676e423b54e689d",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s04/requests.npz": "764259eb618a2ee9393b67ec2713cd0c68763a3e55bbd35e261f5c38ea044b0e",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s04/template-spec.json": "5cc7905cdca67bdf09eb0730a274644f5605178b1c97928572c5ecf2a3b5acff",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s00/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s00/template-spec.json": "452da911a5f3d6d8cbd33e96451d6f65af5e46eee57fda00125c59f6378dfba6",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s01/requests.npz": "929f5b8a23043c0a10790d7cc0683ff81a6049b4e714db86b1fb54cb7f3ca8f2",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s01/template-spec.json": "b943e29941af75b7c4ff333bdc0a9697d0e15131bdea46c4460ef91f894565b2",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s02/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s02/template-spec.json": "412390b67001e08930f243f54954d78e7edf94b330aee2087c35748963a883db",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s03/requests.npz": "be049a344735ad19157ea86c6e911ea9042127ace736fe98bcdddf6b3c1425d1",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s03/template-spec.json": "6d5f2819be44646890cdad1969043bee5209e801b79687a8c1c2205601bc9656",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s04/requests.npz": "764259eb618a2ee9393b67ec2713cd0c68763a3e55bbd35e261f5c38ea044b0e",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s04/template-spec.json": "d8bd2b1b151582ec7495e59a15cae15279f71d444429c5c273397b63008b3440",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--fresh--light-r0/requests.npz": "003a6f6306787b67391735c41dd8b14c689beaaab3ab71a5e9afb376d3cbb091",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--fresh--light-r0/template-spec.json": "df1a6663ea748b0dc0333540877000e5c91d493b151e134e346dee54e834e3de",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--fresh--light-r1/requests.npz": "003a6f6306787b67391735c41dd8b14c689beaaab3ab71a5e9afb376d3cbb091",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--fresh--light-r1/template-spec.json": "32dce4105aaadac4f7079264cf0a30a3f8171862edf59cceaba6624f01a5252d",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--fresh--reference-r0/requests.npz": "003a6f6306787b67391735c41dd8b14c689beaaab3ab71a5e9afb376d3cbb091",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--fresh--reference-r0/template-spec.json": "a0bf214d782ddef0adb5b6f9b89c2d52566a5928b5d96316bddfe12520aa5460",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--prefix--reference-t0018/requests.npz": "adc91d6f97531e8f94b0bbee6b67b1c62b0303bb90b2ad0aa0adf0af9f990570",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--prefix--reference-t0018/template-spec.json": "8400934e175d3c20f19d863082e7df02c5279864b5191736565e9014df6e0e83",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--prefix--reference-t0019/requests.npz": "adc91d6f97531e8f94b0bbee6b67b1c62b0303bb90b2ad0aa0adf0af9f990570",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--prefix--reference-t0019/template-spec.json": "9c361dfb9af4dd7071a7f1c3c2315adddb21b42e9ed5e9a199b1cdf52fab40e7",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--prefix--reference-t0500/requests.npz": "aa2773a740b0e85940f3d96738a141903d5d178e40586522b603ae1c9de53e98",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--prefix--reference-t0500/template-spec.json": "bda640a599d6cdf80ad435f344fcd576d91ca0afe9de732f36fa7bd54d470c1e",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/overlays/static25.json": "b0ee003192fbdfd869f8b23c9bbab0ff99079b7bd2bf1dc33b7afef40785a143",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/overlays/zero.json": "11b668978f3070dad26d99d9310bebefa0731fa0d4e361e8dc0ef02a213277c2",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/AM-gate-authority.json": "66257eb665808e33005dd7ba14a16063064618cc48e47cb65b70f3900cec2484",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/AM-seal-verification.json": "175b5d0e2de12a9ce01c6167591dab882d9c9c6869de2d194bcd9e6732c6ed6d",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/ENGINEERING_GATE_DRAFT.md": "1ac0d65b906e1061781c967cc6a99e8a0a73df6a1ee564ed6603f88e3f5d7056",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_analysis.py": "3970d13bd43d4bc12baf4b6ad1cda3eb085e10bf4648752cfcecb6d12314c5ea",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_compare.py": "5a2403f11bc08d65a9d242ac2cf9686b850e0c3680d65659f785e9b6b50c0238",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_inputs.py": "cc8c0e83016af4836c81cd0773fc521c69fd30e6f4d021bf54d0e7897105c6d5",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_plan.py": "3c127aee723a054fda272fee458067608b521a7c443455822d97f509caded6c7",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_prepare.py": "62dedce2439407398e70beb4c718bf14e02d3e624b3db3ef6f74299115d84bc1",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_queue_audit.py": "6ddaec52f2a0b5d0c528d51230d372fe2344160aef5eccea6a95b6c5e61a574e",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_scopes.py": "1043ba217e5395c9e81e58b95a5aa396f572588872b954e549774f2b99cac5df",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_workflow.py": "76313332b8d18f121a61f7b6e2fc32ea9e893848e8ed5d049557fc08b385e674",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/runtime_continuation.py": "0b8e8e0a6a23a079dc62a88355ce355d53b3ae22f6665519a8f6aef2dcfc5aba",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/runtime_light.py": "522b8c31ea938890fe15364fccd25ccc5bded54101754909f255532e7ad01aae",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_analysis.py": "35e4ee37a1e82cf5e645d24165343049d400104c94a6d184b8aa834ba5ef2d20",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_compare.py": "87a85843d918cce6529ab94f7cb82499aa413281e803c00c030a3c340a581469",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_inputs.py": "4dcc7b775eb3c7e59ed9cc3d7591eacc0ef7bda1209edbd847e2ae79b115ef1b",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_plan.py": "c26c2c75bb27d3b8514b7d44f40369130d60147c6c8edc569b4efba4a4ad9815",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_prepare.py": "a12aa1d2cb4880a3f7a7889b89d71a859bc8c68b4badfb8f082d712cdd342627",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_queue_audit.py": "0e2bcfe25c3b5a5cd0ed5cd05a89392207191ec4db950cdb06a0137666c8adb7",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_scopes.py": "748c0777e4a8164e80c03c727df1c2decbac7747737ad1c9fb730ea5c9e208d3",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_workflow.py": "bb781b23f92b5c0eb92f8dbc54468a8e843177f6da004c444b48947b037bd705",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_runtime_continuation.py": "325c0b688d0ca1648ffdf29a8d3d4bb91d6f6115bea6f5ac30982acd6dfe8e06",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_runtime_light.py": "887345e497e6fa9c10ffa49c490196711d8cee028c62ec7a73f42db36569be2b",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/regression/old-integrity-before.json": "68475cc0e72039e044c8fb3aaea9c8487c6737c1b8a457641e818581d81c387c",
|
||||
"/data/digital-drosophila/experiments/phase4h-dopamine-plasticity/mappings/dan-to-compartment.parquet": "a16f72c3121ed0ec638c1a2b249ace446e6ccee020b49679818eb42589d00662",
|
||||
"/data/digital-drosophila/experiments/phase4h-dopamine-plasticity/mappings/dan-to-mbon-confirmed.parquet": "730d000f25667b59181d2ee6703c64591229a8beab0856197ed71e68d799d191",
|
||||
"/data/digital-drosophila/experiments/phase4h-dopamine-plasticity/mappings/mbon-to-compartment.parquet": "54f371f7e35b9def44becd1ba9bd2872861f4876b255b2c8ec46feee6473b70c",
|
||||
"/data/digital-drosophila/experiments/phase4h-dopamine-plasticity/plastic-mask/plastic-edge-candidates.parquet": "e5075ee3e5a0edf3a4d197453847163cc295b254f21c67203159bba204b12a76",
|
||||
"/data/digital-drosophila/experiments/phase4h-dopamine-plasticity/plastic-mask/plastic-edge-ids.int64.npy": "8b0fb6eb2e6c31da4d17dc20d890aa3f367e514f05642de5bad6b42a1611c05b",
|
||||
"/data/digital-drosophila/experiments/phase4l-olfactory-grounding/odor-encoder/frozen-odor-panel.parquet": "907f16a56e024a8e2112b5751e53b0e6037b329fa110098af3d31b119c10a1a0",
|
||||
"/data/digital-drosophila/experiments/phase4l-olfactory-grounding/odor-encoder/mapped-glomerular-vectors.npz": "f057563152e0fa22060080af13019f319e7f36563a775eff829bbc1929c451b0",
|
||||
"/data/digital-drosophila/experiments/phase4l-olfactory-grounding/odor-encoder/selection.json": "1b832becf9d08935716fe9ba5e3cd3e619e7d208dfb43c4fa197c969d095f113",
|
||||
"/data/digital-drosophila/experiments/phase4l-olfactory-grounding/receptor-mapping/olfactory-mapping.parquet": "a01d27000533e9844458a4c559cac084f1c34ca20a1104e97e6a0f72b0cc93b1",
|
||||
"/data/digital-drosophila/models/male-cns-lif/apl-timing-lab-v1/gpu_timing.py": "af1975ba5e5e700208c0a598d3cbe648a3cf10885c6231239b6e4b28f76d173b",
|
||||
"/data/digital-drosophila/models/male-cns-lif/apl-timing-lab-v1/timing_queue.py": "54df6d4818e2a0c26e96fb0aaf5d9b71cd964981706da937562d48af79aca14e",
|
||||
"/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/gpu_apl.py": "69f5d893f47dafff4ef7c3186c3df0b9014666b32c8f4e943b57016bec92b18a",
|
||||
"/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/legacy_apl_worker.py": "21ceec65fe42581dc55872010e0025d660e80358905f1cf4df1dadf341a3b291",
|
||||
"/data/digital-drosophila/models/male-cns-lif/author-fullgraph-lab-v1/oracle_full.py": "d72003d98f0f1624b12126eff50bd361c43d888f4a64d90ba9247a58976f1961",
|
||||
"/data/digital-drosophila/models/male-cns-lif/author-runtime-lab-v1/author_ext.cpp": "208a937d17bbb041b9bf6b25b89264ee566830b60609e58491b44583d8541f15",
|
||||
"/data/digital-drosophila/models/male-cns-lif/author-runtime-lab-v1/author_ext.cu": "669f166e18ce9a3f63fc723db8b0a8b74f7fa4757194b1bd65b4cf6008a7787e",
|
||||
"/data/digital-drosophila/models/male-cns-lif/author-runtime-lab-v1/gpu_backend.py": "03758d07572f4b44d272059d9308fac534268ad201b57bdd77d69fee95e67278",
|
||||
"/data/digital-drosophila/models/male-cns-lif/mb-physiology-v1/phase4j.py": "abb4574da85f00bd9ef61024c65993ef81d42651ff8d8d63c15dd69c6222471e",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/EVALUATION_POLICY_DRAFT.md": "a84170a61564715a1532f20df4c6a330f0f9725c383db48b8f3e1a4b5fba0bc8",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/EVIDENCE_DRAFT.md": "8455c12e3a6bb1b22a6e38f9017293fe5deea37ba3ec61e13598d00dafc12296",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/PROTOCOL_DRAFT.md": "8ebecb1f3d012ddc29a1cb727269dd277629c53565e09978bf9dbf7140cb8508",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/README_DRAFT.md": "50be97f64097b681355993a8afd7f467ea187e99e88b19ca30561e08d517999f",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/biological_contract.py": "e09f0f2b5e6ec746176e3a1aa2fdee1a15385e14e96bd343d14379a759f3ae43",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/conditioning_inputs.py": "19382e066e450140bb653a3661f980ffe7cc62f412020ef57df0b6e6b3cbb8ba",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/conditioning_update.py": "96efff678cff910654eb08e86f1a17789e4e5589e340345f419c7027a7d547e2",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/draft-source-inventory.json": "2c72d47d09b4ad1949dc6cfdc170f64847ff75f95ded5d20b421fb5a75e0eb84",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/evaluation_plan.py": "991c813ff3322b230947f302b12b04ec382c3b632817f94b698101e4b17efa7d",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/evaluation_policy.py": "21331a9ff3567dc6f6399e16bb91ef486d74231f5db51799beb6dd1bf71d022b",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/metrics.py": "47319e21db3c8b030b1bafbf0703cd86fb588d23bb29436accbacdba73d08c3c",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/seed_registry.py": "0da033b132095ec3087b5d9f64e53c2e391fa50ab0b7653b31296eeb84799b7e",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_biological_contract.py": "0ce796e6ad1a4cbcb9bcb760eff628a9562b4a809cc9c177a9a0d88df68f02b3",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_conditioning_inputs.py": "95e37c770e78ce722a3007c5b371c51aec2989634cddfe5b414ac3fa817e5c22",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_conditioning_update.py": "1c25d93753932ace06abc876fe0867546b3bb330de3e602da6aec7bb4588e4bd",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_evaluation_plan.py": "21d2402025122d8665fb1f32e184fd8e30fc17242810fc70901b7f7fc8c53bfa",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_evaluation_policy.py": "421a31b76eaa547e890c291d2c38a415352d9ccad6fccc800461f522ff4c83f1",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_metrics.py": "1928894d248dd37fad0fc67bc9dcfeac27c4d8be4aec22f54b9ef20a10ea8645",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_seed_registry.py": "7aca38f3c975e3ad4f6337d83b826c09afef336381d124c22ff0eb2eb60a0834",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_trial_plan.py": "927678956ae9959a047b1cd258ee8dee22eb6842a96ff4b2ba2db077310163c9",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/trial_plan.py": "6fed3f494d075339a7e5b001d43b2598640b189e038952fbd4d41200bacac587",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-grounding-v1/phase4l.yaml": "9b8bcb7e031bf9063033a1854a439a7cd0bf6730301c2d2d02ca99a76f098d6e",
|
||||
"/data/digital-drosophila/models/male-cns-lif/phase4l.py": "e97d58d8c1f44920d0e953f8f5831ddc86fa0198784e86460e315de4116ac553",
|
||||
"/data/digital-drosophila/models/male-cns-lif/pn-recruitment-audit-v1/publication.py": "7a79c499098b74163e7bb16adabcbc54e7069dafa204d0b99c7f4c03d79f8016",
|
||||
"/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1/checksums.sha256": "493f541756064d9d65603e550628656a6f2dbf44f8b862ef905e8c3fd2427a43",
|
||||
"/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1/config.json": "c19f00c81f12c4c3503d3d557bd73d0722d4d3fed7279449408c67a89a6ffcf9",
|
||||
"/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1/context.py": "0fa2e0892c973fe70ecbc0613e3cb508c256b7745042f8936edf23dedc31d166",
|
||||
"/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1/eligibility_bridge.py": "174fb8d14619189e74b095e77a6db18b14c93046dc431c0b55710a5aa2dd2e61",
|
||||
"/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1/manifest.json": "7edeb251ecbeac5a64805fefe171a0a0bf8bba2675919ef922cc1a329c203ea8",
|
||||
"/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1/overlay.py": "7f891d0ba79b393c96e75fd2dee2eddc51e57d8213eaac2779703bc2c18712b4"
|
||||
},
|
||||
"schema": "phase4an-epoch-postprocess-authority-v1"
|
||||
}
|
||||
@@ -0,0 +1,292 @@
|
||||
{
|
||||
"checkpoint_dir": "/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/performance--natural-light-fresh",
|
||||
"checkpoint_manifest_sha256": "5cec0f224be49493af884e969cb97d47ac3e000da88c6d0ac8d1b23e3025db8a",
|
||||
"command": {
|
||||
"compartment": "y5B'2a",
|
||||
"d_command": 1.0,
|
||||
"frozen": true,
|
||||
"steps": 1200,
|
||||
"trace_backend": "torch",
|
||||
"us_tick": 900
|
||||
},
|
||||
"diagnostic_mode": "light",
|
||||
"epoch_id": "engineering-residency-control-N_frozen",
|
||||
"files": {
|
||||
"am_overlay_source": {
|
||||
"path": "/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1/overlay.py",
|
||||
"sha256": "7f891d0ba79b393c96e75fd2dee2eddc51e57d8213eaac2779703bc2c18712b4"
|
||||
},
|
||||
"base_candidate": {
|
||||
"path": "/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/protocol/base-candidate.float32-mV.npy",
|
||||
"sha256": "1218d1b328f29a7afefb0ca0b7b6421247f14ad598aa1957a6a7aacbc8cebcae"
|
||||
},
|
||||
"candidate_map": {
|
||||
"path": "/data/digital-drosophila/experiments/phase4ao-conditioning-interface/inputs/static/candidate-map.npz",
|
||||
"sha256": "29dcb57fcaefb5817fa4616b9a75285327b41d8a67cfc0f2ad2bacc14e41f2f0"
|
||||
},
|
||||
"canonical_kc": {
|
||||
"path": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/kc_globals.npy",
|
||||
"sha256": "97a570aafa089f93e642b2bb07e3a3322dabb14c3c7dd431f0c8d2b3b7951fdd"
|
||||
},
|
||||
"conditioning_update_source": {
|
||||
"path": "/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/conditioning_update.py",
|
||||
"sha256": "96efff678cff910654eb08e86f1a17789e4e5589e340345f419c7027a7d547e2"
|
||||
},
|
||||
"eligibility_bridge_source": {
|
||||
"path": "/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1/eligibility_bridge.py",
|
||||
"sha256": "174fb8d14619189e74b095e77a6db18b14c93046dc431c0b55710a5aa2dd2e61"
|
||||
},
|
||||
"kc": {
|
||||
"path": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/kc_globals.npy",
|
||||
"sha256": "97a570aafa089f93e642b2bb07e3a3322dabb14c3c7dd431f0c8d2b3b7951fdd"
|
||||
},
|
||||
"mask": {
|
||||
"path": "/data/digital-drosophila/experiments/phase4h-dopamine-plasticity/plastic-mask/plastic-edge-ids.int64.npy",
|
||||
"sha256": "8b0fb6eb2e6c31da4d17dc20d890aa3f367e514f05642de5bad6b42a1611c05b"
|
||||
},
|
||||
"overlay_before": {
|
||||
"path": "/data/digital-drosophila/experiments/phase4ap-conditioning-interface-v2/updates/D1--reference--epoch-000/delta-after.npz",
|
||||
"sha256": "b89e407a5d93b5f1901f901b00428dc19bd20cee2d81e57b117a2fa68d200a48"
|
||||
},
|
||||
"overlay_manifest_before": {
|
||||
"path": "/data/digital-drosophila/experiments/phase4ap-conditioning-interface-v2/updates/D1--reference--epoch-000/overlay-manifest.json",
|
||||
"sha256": "38dabc55ea0569843ee70f13cf570832ecaa8f1ee7f26a7420e7ebc3ea86f6bd"
|
||||
},
|
||||
"phase4j_source": {
|
||||
"path": "/data/digital-drosophila/models/male-cns-lif/mb-physiology-v1/phase4j.py",
|
||||
"sha256": "abb4574da85f00bd9ef61024c65993ef81d42651ff8d8d63c15dd69c6222471e"
|
||||
},
|
||||
"requests": {
|
||||
"path": "/data/digital-drosophila/experiments/phase4aq-conditioning-execution/cases/performance--natural-light-fresh/requests.npz",
|
||||
"sha256": "571d09c32cabd45af79f71f0f27f7adcc38b9c65daf5ca124366ea439e088143"
|
||||
},
|
||||
"runtime_continuation_source": {
|
||||
"path": "/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/runtime_continuation.py",
|
||||
"sha256": "0b8e8e0a6a23a079dc62a88355ce355d53b3ae22f6665519a8f6aef2dcfc5aba"
|
||||
},
|
||||
"runtime_light_source": {
|
||||
"path": "/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/runtime_light.py",
|
||||
"sha256": "522b8c31ea938890fe15364fccd25ccc5bded54101754909f255532e7ad01aae"
|
||||
},
|
||||
"spec": {
|
||||
"path": "/data/digital-drosophila/experiments/phase4aq-conditioning-execution/cases/performance--natural-light-fresh/spec.json",
|
||||
"sha256": "ea4c40897aceb26edfa5db934647fbc6f6946746441f843bc336f15e5d4e0a23"
|
||||
},
|
||||
"state": {
|
||||
"path": "/data/digital-drosophila/experiments/phase4aq-conditioning-execution/runs/performance--natural-light-fresh/state.npz",
|
||||
"sha256": "137d5a73a869f27df8a3f97002ca6a683c80d3d715057759fb2aad64a05d37ff"
|
||||
}
|
||||
},
|
||||
"frozen_inputs": {
|
||||
"/data/digital-drosophila/datasets/male-cns-v1.0/processed/neuron-only/neuron-index/unified-metadata.parquet": "922af16846a065c3dbfca7c11146b83ca217fcbd7392edc745f444a04eae8c63",
|
||||
"/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json": "bde79d95ef0097b827d5faf4d5658eafc009d8e9fcef1fddd645c953823e3f64",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/apl_globals.npy": "8388c8795d49cfe5b14fda54f76ef3a35030c62ba87bd8ca6334a2dcdf186f19",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/input_matrix.npy": "c4d3df703ea5f1d7402b8255cfa19d9744139ad1048827c23b151d8ba766fec6",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/kc_globals.npy": "97a570aafa089f93e642b2bb07e3a3322dabb14c3c7dd431f0c8d2b3b7951fdd",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/output_matrix.npy": "e2d0a1ccd740e6777245ebf2efcd88bf5e1da9e47308c63ec8e83d451e134a73",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/dst.npy": "ce20f7433f78442c717ad2a7b5394cf4a3b109d990b4be0788040b7b0f4ed150",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/edge_id.npy": "49260615ff2b6432ce3dea9ce2c7ab8f83d06c2fb7491e58e08355fcedf86a30",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/nodes.npy": "5b511a98e8fbf8d65bbc70b93e75ecae19366f650b7842a45611bfad62ed83dc",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/ptr.npy": "fe43420f11e6242a11f8199ae7f097cab4b8a6db181d36f2a46b9e46670acbb4",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/signed_raw.npy": "f9884ccb8930b32420b27c69271df78034a8350fe5a5c9b76a63c259268efc09",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/src.npy": "bfd625ce690fc21eb0a8b9dede831688ab73b789045ba83ddf4baeefeddf1fc3",
|
||||
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/weights.npy": "462839ffc3feb8f6c278044488082b1c8e410e7f23229d6b5e29d1b7042416a1",
|
||||
"/data/digital-drosophila/experiments/phase4ak-apl-timing-validation/cases/seed_validation/seed_validation-physiological-00-s1073741825/requests.npz": "003a6f6306787b67391735c41dd8b14c689beaaab3ab71a5e9afb376d3cbb091",
|
||||
"/data/digital-drosophila/experiments/phase4ak-apl-timing-validation/cases/seed_validation/seed_validation-physiological-00-s1073741825/spec.json": "ebffa677b41e06cb776a987a496a0577bdda135cf3c067ca8017b038ff3fc5c4",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/audit/final-status.json": "18b12c832e156bd6e5ba950f48a49fb908c62104b91bb3e78213f523c8fdc8f9",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/audit/scientific-summary.json": "03f229fc0768d38bb7c2a3c558dbd68c2c3a622cbf96b1b16aef2819b6b67b77",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/audit/static25-complete.json": "1a9cfd096bfc7ab826e043d450a32403a1a7176ab1f7056a3afaceb5c33ac098",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/audit/zero-complete.json": "59397f4b7874894049cc5e77d0555ddcc8274c9573bc53a4bc5f41429683166e",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/checksums.sha256": "fde235a6d781d4c860107c3aa94671811b3f39b167965034ed57f3278e012c3a",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/adapter-provenance.json": "d1b64bdd7b8bc2023dba8321f74bf8ba0a9cac8ded772711f68efeeeb2297156",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/apl-applied.float32.npy": "6228c9e8ec19cb7532e65728ec8f2bd6b080dca8379b17bd393979beaba4c6eb",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/apl-drive.float32.npy": "19b32ccdefea22ddc3e2efcc98b919b8fcf69887f029c17dc75bafa5b34259c5",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/apl-inhibition.float32.npy": "d5194ea98900ca1800416712619143b731d9b3a5d1391180e6881205c7a4d663",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/apl-pending-tail.float32.npy": "2dd2e0c79d4ee5299b8c1e8863e6c61b81f3dba08e599011887b1e1621f7c945",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/apl-state.float32.npy": "5fe5ac53e012232b42a7e717357e9782b247f74da93640a0cfb8a078bc9d4855",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/apl-timing-audit.json": "6ceacfab219fc40146c3e753bdaa96a9e678762f1aeeec04fa303cbf9ebc09be",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/comparison.json": "becda112d4f7576318e2a825daf8f049eb3916c964252511963779899228974c",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/output-hashes.json": "74748bb4cde4769caa31ecc7c888e9e6192fffc022deee94e4378573d0dbc9cc",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/overlay-audit.json": "949d7f986ae2212d44777bd351b88e54c38db857fc062d4d232c2670d31e3085",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/overlay-input.npz": "7805bd2f86de91777bca86c52870607a2e091ed74b901319b896055ad3463f6d",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/overlay-manifest.json": "96d8406b69e98ba9829a52788c6c96888493e8bf34581d6d653226b1eb2e494b",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/queue.jsonl": "3e93bbae67a18944383b2b11a63708ee31e18b8ae7084f24dcb24045c85aa9a7",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/requests.csv": "b11fb0b6d1ac9211f02f05a9809175c64b72e8bcd4c4e4da31be1efbe6a82a83",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/sealed-gpu-source.diff": "0584f865885b18e6a36870a7ecfbbc98d7a94274fa5e9e073e7cf97597d78a03",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/source-audit.json": "d644f0265632f117bba0e045d26fb266765b1d005a89426b6242f3de034be935",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/state.npz": "7de2f62ecbde41a11db5aa220aed2fa6128e9fb6e65d04357f5373eb21538f81",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/summary.json": "6f6fb3ffc5f9df761a7972aa97444c7c095edb359580d19103044fa54bce674f",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/static25/seed_validation-physiological-00-s1073741825-r0/tick-state-hashes.jsonl": "3428c112a32024b539218aa6f4778cfa8c19c208bbdbfb2567324294370f23ea",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/adapter-provenance.json": "46d8ad74b409145c42f9066f992166f114cef2272bb0c6ea40c58438bdd39c13",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/apl-applied.float32.npy": "b3a535bc095db2464a75560ed11f336a9db8e843c08fd7681a1b9759b624ad8e",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/apl-drive.float32.npy": "8b6432e8947f4c67466b5cae28cb0d0877b61862e80e6d9b10c5734d9afa8411",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/apl-inhibition.float32.npy": "8f9e59026dc7c7663abf8f7abc60ebf93b11a68483bc0960d375a83731acc859",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/apl-pending-tail.float32.npy": "fc1e2d8ffa426d4118a7544129323c5f7523e9df3e298a60922ca0ecabe7c18f",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/apl-state.float32.npy": "36ecfec747be0c700959ba1ac171b81a1f3471aa9baba41b7bb6a67be01213c2",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/apl-timing-audit.json": "850600c0560f98c1f2de35bae506c5619205375e6616137a7e8ff978000b0c3a",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/comparison.json": "3e55e8edaf7e3cf4453e37cf90d7a420808977665174ccf525dfef7553418d46",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/output-hashes.json": "aabd9f46a9697440f0cc0204455e831d16b7aadfdebe3e5a8c986bfe85d05300",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/overlay-audit.json": "22d13f7d6ad27cbe117e01117d46c0457781adf3a0bf2aa6748fe7f4b484aa56",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/overlay-input.npz": "0b219eab09c30dc3af31fef7e6395a9bec1234090abbb72db096da833fed82c5",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/overlay-manifest.json": "902933628aabc9e084b547dfdaff0f8361d353949ba3ee92439a2f35d8625d8a",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/queue.jsonl": "22fbf106279d5ad314beba357137701df111bb28b57accdb09a0e299dfdf39cf",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/requests.csv": "4bcc9ef7fdc596ddac3be3b0d29f0aea2e086deeb803f3a90baba21b5490ef53",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/sealed-gpu-source.diff": "0584f865885b18e6a36870a7ecfbbc98d7a94274fa5e9e073e7cf97597d78a03",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/source-audit.json": "d644f0265632f117bba0e045d26fb266765b1d005a89426b6242f3de034be935",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/state.npz": "933afdc1bd0ea81174aeb334f017cfbe1bbc0a72f8eca767698275c5dca886f3",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/summary.json": "244be6a69b8276a212b1601ab7235e58c0bd9d523c88368025b29f4b4664ddcf",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/gpu/zero/seed_validation-physiological-00-s1073741825-r0/tick-state-hashes.jsonl": "0266afe78eadd1ea5bfb25026103d01d2af82d9b6ce2bcbb9d60e576ac898e91",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/manifest.json": "9e24b682935a9b18e05db7a933080c5f63ddbeb8a0c85cc0df1cfe1d06d88ab4",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/overlays/static25.json": "96d8406b69e98ba9829a52788c6c96888493e8bf34581d6d653226b1eb2e494b",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/overlays/static25.npz": "7805bd2f86de91777bca86c52870607a2e091ed74b901319b896055ad3463f6d",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/overlays/zero.json": "902933628aabc9e084b547dfdaff0f8361d353949ba3ee92439a2f35d8625d8a",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/overlays/zero.npz": "0b219eab09c30dc3af31fef7e6395a9bec1234090abbb72db096da833fed82c5",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/protocol/base-candidate.float32-mV.npy": "1218d1b328f29a7afefb0ca0b7b6421247f14ad598aa1957a6a7aacbc8cebcae",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/protocol/prepared-hashes.json": "4af0bccbb9153be0d8cb65c5e4150946be3396ca351eab52b273c86459200580",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/protocol/preregistered.json": "465886b78ada08092c2c83de278844707499718977fb6dc6a7608391da0e5304",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/regression/frozen-five.json": "905c64c8b3f7de942d55f6ecb76c27c42821691a9fd3e0c17ffb466e1de0fea0",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/regression/old-integrity-after.json": "7d3de4ba6248cc52960087bcfa2658f9b8ee34d9ac08c56380f7018c34097929",
|
||||
"/data/digital-drosophila/experiments/phase4am-wholebrain-plastic-interface/regression/old-integrity-before.json": "7d3de4ba6248cc52960087bcfa2658f9b8ee34d9ac08c56380f7018c34097929",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s00/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s00/template-spec.json": "065e4b01b74ac6619f6533c54fdb58a345fffe7be30ae2295e50ab7015da888a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s01/requests.npz": "929f5b8a23043c0a10790d7cc0683ff81a6049b4e714db86b1fb54cb7f3ca8f2",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s01/template-spec.json": "38001935f07393a08f8c83595541a6ff060b0f9ca7b9fdaf357e2f77f9348994",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s02/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s02/template-spec.json": "c89d7994d40fc79591c78d11c549766b45d283145fdcebb1e3b6c964b8750b2a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s03/requests.npz": "be049a344735ad19157ea86c6e911ea9042127ace736fe98bcdddf6b3c1425d1",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s03/template-spec.json": "390f3d472a2baf3b7d14f1bb22185e027fb1c5ede8f42bfbd8e7c2051e78d0fe",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s04/requests.npz": "764259eb618a2ee9393b67ec2713cd0c68763a3e55bbd35e261f5c38ea044b0e",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--light-s04/template-spec.json": "90a262080e33a6014679e7f3d932f61e1edb04cffcd9a2cf35440c078a9085f4",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s00/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s00/template-spec.json": "3b63e236d755714dc59b083b2ee48761ce48e9a8456770e3502798f5bd5e2ff6",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s01/requests.npz": "929f5b8a23043c0a10790d7cc0683ff81a6049b4e714db86b1fb54cb7f3ca8f2",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s01/template-spec.json": "595a1a67fd82b48e0db25480771a93bd289e8f65c511c43780b42dabf9c8b478",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s02/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s02/template-spec.json": "bda9afb21aebd4cf37d52a0cb83c21f179ca4fe9aca8a43e5a1cc92f2af81897",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s03/requests.npz": "be049a344735ad19157ea86c6e911ea9042127ace736fe98bcdddf6b3c1425d1",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s03/template-spec.json": "246cbb287972c7539c4f53bc2546bd9cdd0dd960e8714bce060db1bee1ba0fc9",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s04/requests.npz": "764259eb618a2ee9393b67ec2713cd0c68763a3e55bbd35e261f5c38ea044b0e",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--chain--reference-s04/template-spec.json": "de59abaa0670a9be8d90a9dd9b41522edd277d9f75dbdb77ddeeeca1c508265f",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--fresh--light-r0/requests.npz": "003a6f6306787b67391735c41dd8b14c689beaaab3ab71a5e9afb376d3cbb091",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--fresh--light-r0/template-spec.json": "802b717691f9a6b460a1a58044286e727ffa8393605127ee7a11ad267fbf6338",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--fresh--light-r1/requests.npz": "003a6f6306787b67391735c41dd8b14c689beaaab3ab71a5e9afb376d3cbb091",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--fresh--light-r1/template-spec.json": "f4cdfd5de0fb80dd39203425c4ff7d063b0b66f2ac887e4276043251e3ad956c",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--fresh--reference-r0/requests.npz": "003a6f6306787b67391735c41dd8b14c689beaaab3ab71a5e9afb376d3cbb091",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--fresh--reference-r0/template-spec.json": "2ee541997a8a82f9ac356e9fedf8fc70ce31f622d42d846ab6de8c5f6cdea39f",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--prefix--reference-t0018/requests.npz": "adc91d6f97531e8f94b0bbee6b67b1c62b0303bb90b2ad0aa0adf0af9f990570",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--prefix--reference-t0018/template-spec.json": "282eccfb1ee2008f0b9ae8cca4daf45bfefd664806e7d04b8712fadf90b83bb5",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--prefix--reference-t0019/requests.npz": "adc91d6f97531e8f94b0bbee6b67b1c62b0303bb90b2ad0aa0adf0af9f990570",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--prefix--reference-t0019/template-spec.json": "8cd7512a1b2cdef47aecfd26bfb7ee8b22b566dc6c6812e887b4cc3f5416e7e3",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--prefix--reference-t0500/requests.npz": "aa2773a740b0e85940f3d96738a141903d5d178e40586522b603ae1c9de53e98",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/static25--prefix--reference-t0500/template-spec.json": "654043502385a40dc4396c25ab2bf6f74701a7026fc85e6789672a810e5f700e",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s00/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s00/template-spec.json": "e8f6fe8e0f67cbe851c045a067485d753979f5af32d30f596f545387b306f123",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s01/requests.npz": "929f5b8a23043c0a10790d7cc0683ff81a6049b4e714db86b1fb54cb7f3ca8f2",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s01/template-spec.json": "b727d54f9d28e9b8482860c3ed2bb6c30d4778fe90644b2df9ebb8d0c032e148",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s02/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s02/template-spec.json": "8af5bc5ed35084f15c7d77ded8224d49f49561d48510c862410eccd4d7dc5560",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s03/requests.npz": "be049a344735ad19157ea86c6e911ea9042127ace736fe98bcdddf6b3c1425d1",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s03/template-spec.json": "7e140b41ae610cd67a8cfe2e30d633190ac2c7689a4682bba676e423b54e689d",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s04/requests.npz": "764259eb618a2ee9393b67ec2713cd0c68763a3e55bbd35e261f5c38ea044b0e",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--light-s04/template-spec.json": "5cc7905cdca67bdf09eb0730a274644f5605178b1c97928572c5ecf2a3b5acff",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s00/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s00/template-spec.json": "452da911a5f3d6d8cbd33e96451d6f65af5e46eee57fda00125c59f6378dfba6",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s01/requests.npz": "929f5b8a23043c0a10790d7cc0683ff81a6049b4e714db86b1fb54cb7f3ca8f2",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s01/template-spec.json": "b943e29941af75b7c4ff333bdc0a9697d0e15131bdea46c4460ef91f894565b2",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s02/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s02/template-spec.json": "412390b67001e08930f243f54954d78e7edf94b330aee2087c35748963a883db",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s03/requests.npz": "be049a344735ad19157ea86c6e911ea9042127ace736fe98bcdddf6b3c1425d1",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s03/template-spec.json": "6d5f2819be44646890cdad1969043bee5209e801b79687a8c1c2205601bc9656",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s04/requests.npz": "764259eb618a2ee9393b67ec2713cd0c68763a3e55bbd35e261f5c38ea044b0e",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--chain--reference-s04/template-spec.json": "d8bd2b1b151582ec7495e59a15cae15279f71d444429c5c273397b63008b3440",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--fresh--light-r0/requests.npz": "003a6f6306787b67391735c41dd8b14c689beaaab3ab71a5e9afb376d3cbb091",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--fresh--light-r0/template-spec.json": "df1a6663ea748b0dc0333540877000e5c91d493b151e134e346dee54e834e3de",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--fresh--light-r1/requests.npz": "003a6f6306787b67391735c41dd8b14c689beaaab3ab71a5e9afb376d3cbb091",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--fresh--light-r1/template-spec.json": "32dce4105aaadac4f7079264cf0a30a3f8171862edf59cceaba6624f01a5252d",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--fresh--reference-r0/requests.npz": "003a6f6306787b67391735c41dd8b14c689beaaab3ab71a5e9afb376d3cbb091",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--fresh--reference-r0/template-spec.json": "a0bf214d782ddef0adb5b6f9b89c2d52566a5928b5d96316bddfe12520aa5460",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--prefix--reference-t0018/requests.npz": "adc91d6f97531e8f94b0bbee6b67b1c62b0303bb90b2ad0aa0adf0af9f990570",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--prefix--reference-t0018/template-spec.json": "8400934e175d3c20f19d863082e7df02c5279864b5191736565e9014df6e0e83",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--prefix--reference-t0019/requests.npz": "adc91d6f97531e8f94b0bbee6b67b1c62b0303bb90b2ad0aa0adf0af9f990570",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--prefix--reference-t0019/template-spec.json": "9c361dfb9af4dd7071a7f1c3c2315adddb21b42e9ed5e9a199b1cdf52fab40e7",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--prefix--reference-t0500/requests.npz": "aa2773a740b0e85940f3d96738a141903d5d178e40586522b603ae1c9de53e98",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/cases/zero--prefix--reference-t0500/template-spec.json": "bda640a599d6cdf80ad435f344fcd576d91ca0afe9de732f36fa7bd54d470c1e",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/overlays/static25.json": "b0ee003192fbdfd869f8b23c9bbab0ff99079b7bd2bf1dc33b7afef40785a143",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/overlays/zero.json": "11b668978f3070dad26d99d9310bebefa0731fa0d4e361e8dc0ef02a213277c2",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/AM-gate-authority.json": "66257eb665808e33005dd7ba14a16063064618cc48e47cb65b70f3900cec2484",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/AM-seal-verification.json": "175b5d0e2de12a9ce01c6167591dab882d9c9c6869de2d194bcd9e6732c6ed6d",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/ENGINEERING_GATE_DRAFT.md": "1ac0d65b906e1061781c967cc6a99e8a0a73df6a1ee564ed6603f88e3f5d7056",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_analysis.py": "3970d13bd43d4bc12baf4b6ad1cda3eb085e10bf4648752cfcecb6d12314c5ea",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_compare.py": "5a2403f11bc08d65a9d242ac2cf9686b850e0c3680d65659f785e9b6b50c0238",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_inputs.py": "cc8c0e83016af4836c81cd0773fc521c69fd30e6f4d021bf54d0e7897105c6d5",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_plan.py": "3c127aee723a054fda272fee458067608b521a7c443455822d97f509caded6c7",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_prepare.py": "62dedce2439407398e70beb4c718bf14e02d3e624b3db3ef6f74299115d84bc1",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_queue_audit.py": "6ddaec52f2a0b5d0c528d51230d372fe2344160aef5eccea6a95b6c5e61a574e",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_scopes.py": "1043ba217e5395c9e81e58b95a5aa396f572588872b954e549774f2b99cac5df",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/engineering_workflow.py": "76313332b8d18f121a61f7b6e2fc32ea9e893848e8ed5d049557fc08b385e674",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/runtime_continuation.py": "0b8e8e0a6a23a079dc62a88355ce355d53b3ae22f6665519a8f6aef2dcfc5aba",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/runtime_light.py": "522b8c31ea938890fe15364fccd25ccc5bded54101754909f255532e7ad01aae",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_analysis.py": "35e4ee37a1e82cf5e645d24165343049d400104c94a6d184b8aa834ba5ef2d20",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_compare.py": "87a85843d918cce6529ab94f7cb82499aa413281e803c00c030a3c340a581469",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_inputs.py": "4dcc7b775eb3c7e59ed9cc3d7591eacc0ef7bda1209edbd847e2ae79b115ef1b",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_plan.py": "c26c2c75bb27d3b8514b7d44f40369130d60147c6c8edc569b4efba4a4ad9815",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_prepare.py": "a12aa1d2cb4880a3f7a7889b89d71a859bc8c68b4badfb8f082d712cdd342627",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_queue_audit.py": "0e2bcfe25c3b5a5cd0ed5cd05a89392207191ec4db950cdb06a0137666c8adb7",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_scopes.py": "748c0777e4a8164e80c03c727df1c2decbac7747737ad1c9fb730ea5c9e208d3",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_engineering_workflow.py": "bb781b23f92b5c0eb92f8dbc54468a8e843177f6da004c444b48947b037bd705",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_runtime_continuation.py": "325c0b688d0ca1648ffdf29a8d3d4bb91d6f6115bea6f5ac30982acd6dfe8e06",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/protocol/source-snapshot/test_runtime_light.py": "887345e497e6fa9c10ffa49c490196711d8cee028c62ec7a73f42db36569be2b",
|
||||
"/data/digital-drosophila/experiments/phase4an-engineering-validation/regression/old-integrity-before.json": "68475cc0e72039e044c8fb3aaea9c8487c6737c1b8a457641e818581d81c387c",
|
||||
"/data/digital-drosophila/experiments/phase4h-dopamine-plasticity/mappings/dan-to-compartment.parquet": "a16f72c3121ed0ec638c1a2b249ace446e6ccee020b49679818eb42589d00662",
|
||||
"/data/digital-drosophila/experiments/phase4h-dopamine-plasticity/mappings/dan-to-mbon-confirmed.parquet": "730d000f25667b59181d2ee6703c64591229a8beab0856197ed71e68d799d191",
|
||||
"/data/digital-drosophila/experiments/phase4h-dopamine-plasticity/mappings/mbon-to-compartment.parquet": "54f371f7e35b9def44becd1ba9bd2872861f4876b255b2c8ec46feee6473b70c",
|
||||
"/data/digital-drosophila/experiments/phase4h-dopamine-plasticity/plastic-mask/plastic-edge-candidates.parquet": "e5075ee3e5a0edf3a4d197453847163cc295b254f21c67203159bba204b12a76",
|
||||
"/data/digital-drosophila/experiments/phase4h-dopamine-plasticity/plastic-mask/plastic-edge-ids.int64.npy": "8b0fb6eb2e6c31da4d17dc20d890aa3f367e514f05642de5bad6b42a1611c05b",
|
||||
"/data/digital-drosophila/experiments/phase4l-olfactory-grounding/odor-encoder/frozen-odor-panel.parquet": "907f16a56e024a8e2112b5751e53b0e6037b329fa110098af3d31b119c10a1a0",
|
||||
"/data/digital-drosophila/experiments/phase4l-olfactory-grounding/odor-encoder/mapped-glomerular-vectors.npz": "f057563152e0fa22060080af13019f319e7f36563a775eff829bbc1929c451b0",
|
||||
"/data/digital-drosophila/experiments/phase4l-olfactory-grounding/odor-encoder/selection.json": "1b832becf9d08935716fe9ba5e3cd3e619e7d208dfb43c4fa197c969d095f113",
|
||||
"/data/digital-drosophila/experiments/phase4l-olfactory-grounding/receptor-mapping/olfactory-mapping.parquet": "a01d27000533e9844458a4c559cac084f1c34ca20a1104e97e6a0f72b0cc93b1",
|
||||
"/data/digital-drosophila/models/male-cns-lif/apl-timing-lab-v1/gpu_timing.py": "af1975ba5e5e700208c0a598d3cbe648a3cf10885c6231239b6e4b28f76d173b",
|
||||
"/data/digital-drosophila/models/male-cns-lif/apl-timing-lab-v1/timing_queue.py": "54df6d4818e2a0c26e96fb0aaf5d9b71cd964981706da937562d48af79aca14e",
|
||||
"/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/gpu_apl.py": "69f5d893f47dafff4ef7c3186c3df0b9014666b32c8f4e943b57016bec92b18a",
|
||||
"/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/legacy_apl_worker.py": "21ceec65fe42581dc55872010e0025d660e80358905f1cf4df1dadf341a3b291",
|
||||
"/data/digital-drosophila/models/male-cns-lif/author-fullgraph-lab-v1/oracle_full.py": "d72003d98f0f1624b12126eff50bd361c43d888f4a64d90ba9247a58976f1961",
|
||||
"/data/digital-drosophila/models/male-cns-lif/author-runtime-lab-v1/author_ext.cpp": "208a937d17bbb041b9bf6b25b89264ee566830b60609e58491b44583d8541f15",
|
||||
"/data/digital-drosophila/models/male-cns-lif/author-runtime-lab-v1/author_ext.cu": "669f166e18ce9a3f63fc723db8b0a8b74f7fa4757194b1bd65b4cf6008a7787e",
|
||||
"/data/digital-drosophila/models/male-cns-lif/author-runtime-lab-v1/gpu_backend.py": "03758d07572f4b44d272059d9308fac534268ad201b57bdd77d69fee95e67278",
|
||||
"/data/digital-drosophila/models/male-cns-lif/mb-physiology-v1/phase4j.py": "abb4574da85f00bd9ef61024c65993ef81d42651ff8d8d63c15dd69c6222471e",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/EVALUATION_POLICY_DRAFT.md": "a84170a61564715a1532f20df4c6a330f0f9725c383db48b8f3e1a4b5fba0bc8",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/EVIDENCE_DRAFT.md": "8455c12e3a6bb1b22a6e38f9017293fe5deea37ba3ec61e13598d00dafc12296",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/PROTOCOL_DRAFT.md": "8ebecb1f3d012ddc29a1cb727269dd277629c53565e09978bf9dbf7140cb8508",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/README_DRAFT.md": "50be97f64097b681355993a8afd7f467ea187e99e88b19ca30561e08d517999f",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/biological_contract.py": "e09f0f2b5e6ec746176e3a1aa2fdee1a15385e14e96bd343d14379a759f3ae43",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/conditioning_inputs.py": "19382e066e450140bb653a3661f980ffe7cc62f412020ef57df0b6e6b3cbb8ba",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/conditioning_update.py": "96efff678cff910654eb08e86f1a17789e4e5589e340345f419c7027a7d547e2",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/draft-source-inventory.json": "2c72d47d09b4ad1949dc6cfdc170f64847ff75f95ded5d20b421fb5a75e0eb84",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/evaluation_plan.py": "991c813ff3322b230947f302b12b04ec382c3b632817f94b698101e4b17efa7d",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/evaluation_policy.py": "21331a9ff3567dc6f6399e16bb91ef486d74231f5db51799beb6dd1bf71d022b",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/metrics.py": "47319e21db3c8b030b1bafbf0703cd86fb588d23bb29436accbacdba73d08c3c",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/seed_registry.py": "0da033b132095ec3087b5d9f64e53c2e391fa50ab0b7653b31296eeb84799b7e",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_biological_contract.py": "0ce796e6ad1a4cbcb9bcb760eff628a9562b4a809cc9c177a9a0d88df68f02b3",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_conditioning_inputs.py": "95e37c770e78ce722a3007c5b371c51aec2989634cddfe5b414ac3fa817e5c22",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_conditioning_update.py": "1c25d93753932ace06abc876fe0867546b3bb330de3e602da6aec7bb4588e4bd",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_evaluation_plan.py": "21d2402025122d8665fb1f32e184fd8e30fc17242810fc70901b7f7fc8c53bfa",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_evaluation_policy.py": "421a31b76eaa547e890c291d2c38a415352d9ccad6fccc800461f522ff4c83f1",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_metrics.py": "1928894d248dd37fad0fc67bc9dcfeac27c4d8be4aec22f54b9ef20a10ea8645",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_seed_registry.py": "7aca38f3c975e3ad4f6337d83b826c09afef336381d124c22ff0eb2eb60a0834",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/test_trial_plan.py": "927678956ae9959a047b1cd258ee8dee22eb6842a96ff4b2ba2db077310163c9",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/trial_plan.py": "6fed3f494d075339a7e5b001d43b2598640b189e038952fbd4d41200bacac587",
|
||||
"/data/digital-drosophila/models/male-cns-lif/olfactory-grounding-v1/phase4l.yaml": "9b8bcb7e031bf9063033a1854a439a7cd0bf6730301c2d2d02ca99a76f098d6e",
|
||||
"/data/digital-drosophila/models/male-cns-lif/phase4l.py": "e97d58d8c1f44920d0e953f8f5831ddc86fa0198784e86460e315de4116ac553",
|
||||
"/data/digital-drosophila/models/male-cns-lif/pn-recruitment-audit-v1/publication.py": "7a79c499098b74163e7bb16adabcbc54e7069dafa204d0b99c7f4c03d79f8016",
|
||||
"/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1/checksums.sha256": "493f541756064d9d65603e550628656a6f2dbf44f8b862ef905e8c3fd2427a43",
|
||||
"/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1/config.json": "c19f00c81f12c4c3503d3d557bd73d0722d4d3fed7279449408c67a89a6ffcf9",
|
||||
"/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1/context.py": "0fa2e0892c973fe70ecbc0613e3cb508c256b7745042f8936edf23dedc31d166",
|
||||
"/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1/eligibility_bridge.py": "174fb8d14619189e74b095e77a6db18b14c93046dc431c0b55710a5aa2dd2e61",
|
||||
"/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1/manifest.json": "7edeb251ecbeac5a64805fefe171a0a0bf8bba2675919ef922cc1a329c203ea8",
|
||||
"/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1/overlay.py": "7f891d0ba79b393c96e75fd2dee2eddc51e57d8213eaac2779703bc2c18712b4"
|
||||
},
|
||||
"schema": "phase4an-epoch-postprocess-authority-v1"
|
||||
}
|
||||
@@ -0,0 +1,685 @@
|
||||
{
|
||||
"files": {
|
||||
"00-M-comparison.json": {
|
||||
"bytes": 672,
|
||||
"sha256": "39a687e4d429487fe20e859f4572f9e5245da94d7e8c7a74d51416be56f63904"
|
||||
},
|
||||
"01-N-comparison.json": {
|
||||
"bytes": 670,
|
||||
"sha256": "4c16e45b8b4e597e4a2bb5fe67959a8964cbaa4b554b6dc369c278522f309b07"
|
||||
},
|
||||
"02-M-comparison.json": {
|
||||
"bytes": 669,
|
||||
"sha256": "e01e6117630928ae5d897543d9a80f13f041e166fe2f5cecc255f33b4a55bfb7"
|
||||
},
|
||||
"03-N_D0-comparison.json": {
|
||||
"bytes": 676,
|
||||
"sha256": "b4929d59d6adeb523682f35a1338a2606ac3bc75ba81c6036e71ff6319988175"
|
||||
},
|
||||
"04-N_frozen-comparison.json": {
|
||||
"bytes": 679,
|
||||
"sha256": "5f306ff308e74e2b46c4f29308bb304abb6b96af7b98b4a63c8f50008a784037"
|
||||
},
|
||||
"05-M_D0-comparison.json": {
|
||||
"bytes": 674,
|
||||
"sha256": "de2b9eb21c157c5e0c0df49d00b99720fb4862fda2c2ebd276bf24df6b54e611"
|
||||
},
|
||||
"06-M-comparison.json": {
|
||||
"bytes": 674,
|
||||
"sha256": "be3a1b940c47cd17937cb1a9e9fc6a3e9a3bb018e3efbc0375821404a74f038f"
|
||||
},
|
||||
"benchmark-plan.json": {
|
||||
"bytes": 53491,
|
||||
"sha256": "ad9b906f90eb742706acc4cfe676a845900ad850f2482d0e8fb42d8faf3d71d1"
|
||||
},
|
||||
"inputs/M_D0.authority.json": {
|
||||
"bytes": 44124,
|
||||
"sha256": "56d89454417c4c7d8e4dd1dc3437ad0df55ded706b9e603681bbf491338cbf04"
|
||||
},
|
||||
"inputs/N_D0.authority.json": {
|
||||
"bytes": 44218,
|
||||
"sha256": "4a7ee78ca0671efa0cb5203f7ba405ae3a53b3e23ebfcb8bf52887ce20c0f40b"
|
||||
},
|
||||
"inputs/N_frozen.authority.json": {
|
||||
"bytes": 44221,
|
||||
"sha256": "3063f74a5dbbfb6afa92ee7692bbb0626017b0451072b838be2f9e0bc58748e3"
|
||||
},
|
||||
"logs/00-M-fresh-E.stderr.log": {
|
||||
"bytes": 0,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"logs/00-M-fresh-V.stderr.log": {
|
||||
"bytes": 0,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"logs/01-N-fresh-E.stderr.log": {
|
||||
"bytes": 0,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"logs/01-N-fresh-V.stderr.log": {
|
||||
"bytes": 0,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"logs/02-M-fresh-E.stderr.log": {
|
||||
"bytes": 0,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"logs/02-M-fresh-V.stderr.log": {
|
||||
"bytes": 0,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"logs/03-N_D0-fresh-E.stderr.log": {
|
||||
"bytes": 0,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"logs/03-N_D0-fresh-V.stderr.log": {
|
||||
"bytes": 0,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"logs/04-N_frozen-fresh-E.stderr.log": {
|
||||
"bytes": 0,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"logs/04-N_frozen-fresh-V.stderr.log": {
|
||||
"bytes": 0,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"logs/05-M_D0-fresh-E.stderr.log": {
|
||||
"bytes": 0,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"logs/05-M_D0-fresh-V.stderr.log": {
|
||||
"bytes": 0,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"logs/06-M-fresh-E.stderr.log": {
|
||||
"bytes": 0,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"logs/06-M-fresh-V.stderr.log": {
|
||||
"bytes": 0,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"logs/resident-E.stderr.log": {
|
||||
"bytes": 0,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"logs/resident-V.stderr.log": {
|
||||
"bytes": 0,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"processes/00-M-fresh-E.json": {
|
||||
"bytes": 753,
|
||||
"sha256": "99efe36c00689aedf8b2d03125881c26089dd7070852e53e97a235fd5c566286"
|
||||
},
|
||||
"processes/00-M-fresh-V.json": {
|
||||
"bytes": 772,
|
||||
"sha256": "f4a5416aa8a846f68dbc6a07794ff63114e4c1ce103bca421b512bfe880e9f2d"
|
||||
},
|
||||
"processes/01-N-fresh-E.json": {
|
||||
"bytes": 753,
|
||||
"sha256": "8c5d547f1cc88d2cdcb45d2673fbd95e4c62f3065d8b752c4397e5904a426fbf"
|
||||
},
|
||||
"processes/01-N-fresh-V.json": {
|
||||
"bytes": 772,
|
||||
"sha256": "9f06a8339443eff51d54a9824d662f993dcd0e2984d25293bab180691e4d2b22"
|
||||
},
|
||||
"processes/02-M-fresh-E.json": {
|
||||
"bytes": 752,
|
||||
"sha256": "31595cf71a13d08075c50bf4de5780f988d8cb8b50dc19c406c3ea120d9ca1b7"
|
||||
},
|
||||
"processes/02-M-fresh-V.json": {
|
||||
"bytes": 772,
|
||||
"sha256": "cd97bf45bb88e7ec96019efa59b5e181bc3c08f9f220f8754f86cec8ca6999ac"
|
||||
},
|
||||
"processes/03-N_D0-fresh-E.json": {
|
||||
"bytes": 753,
|
||||
"sha256": "91d3ea18146ffbda446cc6ee3517db75fe7097365fa5639d0a22474e64198bf1"
|
||||
},
|
||||
"processes/03-N_D0-fresh-V.json": {
|
||||
"bytes": 773,
|
||||
"sha256": "928d1d53a117ac74dc6bb548e2fe8b164a96dd3b50e95df3d25c7b40ee8c149a"
|
||||
},
|
||||
"processes/04-N_frozen-fresh-E.json": {
|
||||
"bytes": 752,
|
||||
"sha256": "4579c057330a326802fbfac2a963667709348e6c1075608f71298bd62bab2e4d"
|
||||
},
|
||||
"processes/04-N_frozen-fresh-V.json": {
|
||||
"bytes": 773,
|
||||
"sha256": "6080b54205941320e5a44eef0d4909a36e42f1e3eb7c1a57cbca7375c0d331ed"
|
||||
},
|
||||
"processes/05-M_D0-fresh-E.json": {
|
||||
"bytes": 752,
|
||||
"sha256": "cd92d6f19c7b18a6a2bf08105b4bb843a30ff6ddf0537ffa2fe57649e7b914f5"
|
||||
},
|
||||
"processes/05-M_D0-fresh-V.json": {
|
||||
"bytes": 771,
|
||||
"sha256": "3468ad068a18e331b1788d39bf7982b18c193b710ad441c54e83bf12abd05ee9"
|
||||
},
|
||||
"processes/06-M-fresh-E.json": {
|
||||
"bytes": 753,
|
||||
"sha256": "7ab517b43442e3bcc635c76a3a465982438cc60aae8cb0f2422ff3edca005692"
|
||||
},
|
||||
"processes/06-M-fresh-V.json": {
|
||||
"bytes": 773,
|
||||
"sha256": "bf743182d595508a7938c2c2b94987017c8c576a7b1c37c3f43ab773cfc0c893"
|
||||
},
|
||||
"processes/resident-E.json": {
|
||||
"bytes": 757,
|
||||
"sha256": "b24e427266675f7076e9d9d125eee3eda194a75b16a3d4b95ec897d322179038"
|
||||
},
|
||||
"processes/resident-V.json": {
|
||||
"bytes": 774,
|
||||
"sha256": "a8aebd5ee47bbe168fde923cc59dc77010aa6e2ac8d210e66247fa95ce87829d"
|
||||
},
|
||||
"report.json": {
|
||||
"bytes": 7021,
|
||||
"sha256": "cbc17c10871514279adb6b38338511daa0588ba8f8c91129787c84fd51885339"
|
||||
},
|
||||
"requests/00-M-fresh-E-00.json": {
|
||||
"bytes": 359,
|
||||
"sha256": "0c036fcc5d60f389717dbdb79514a36b8e04ec05bac739f5972e768fdfa65016"
|
||||
},
|
||||
"requests/00-M-fresh-V-00.json": {
|
||||
"bytes": 482,
|
||||
"sha256": "87ad30611b54095773649bb7da4079a256f2ec07bd597a4493adf4127299cd67"
|
||||
},
|
||||
"requests/01-N-fresh-E-00.json": {
|
||||
"bytes": 367,
|
||||
"sha256": "285a45dda2ed0d6b4307397923f2bb32dbc1568eebef48e80c3726f9cf28d4e6"
|
||||
},
|
||||
"requests/01-N-fresh-V-00.json": {
|
||||
"bytes": 490,
|
||||
"sha256": "019f1b8e1717633f2c130bf06158c2fe6bfd41d6e61d598315da5c9a30492099"
|
||||
},
|
||||
"requests/02-M-fresh-E-00.json": {
|
||||
"bytes": 359,
|
||||
"sha256": "ff755e750ab54ddae2fb65527e735bdf7aa149a511c13c04dd3a720ead945ba3"
|
||||
},
|
||||
"requests/02-M-fresh-V-00.json": {
|
||||
"bytes": 482,
|
||||
"sha256": "e831726822ab61fda8a5278aac1c0c28909dc1c05cfda2869b5e81fe64935817"
|
||||
},
|
||||
"requests/03-N_D0-fresh-E-00.json": {
|
||||
"bytes": 306,
|
||||
"sha256": "e1d460664e725554207816e66e55e95059a52675812d6d9c38b6209a793d3ca0"
|
||||
},
|
||||
"requests/03-N_D0-fresh-V-00.json": {
|
||||
"bytes": 432,
|
||||
"sha256": "709d3eaf0f4e678072543e8f5754bc5f82c0868b9aa91169c02cac13f072c0a6"
|
||||
},
|
||||
"requests/04-N_frozen-fresh-E-00.json": {
|
||||
"bytes": 314,
|
||||
"sha256": "b16faa5981d7285a7878228a6d9bdc88eed8c536c96248df665d8d8580d22c50"
|
||||
},
|
||||
"requests/04-N_frozen-fresh-V-00.json": {
|
||||
"bytes": 444,
|
||||
"sha256": "761589d06ef5a140d8308ff54ba334eea1c2b13af9b3a55b72bf492a59e179b9"
|
||||
},
|
||||
"requests/05-M_D0-fresh-E-00.json": {
|
||||
"bytes": 306,
|
||||
"sha256": "e19cd608d72b87e7a75ef1aea53e2d037c92e3be54aa17fbd62bb5f213f2599d"
|
||||
},
|
||||
"requests/05-M_D0-fresh-V-00.json": {
|
||||
"bytes": 432,
|
||||
"sha256": "bb8a9b43ce0d7ffa752a87ea596f0f0cfe530048a6e48b030aa2e330908b3174"
|
||||
},
|
||||
"requests/06-M-fresh-E-00.json": {
|
||||
"bytes": 359,
|
||||
"sha256": "5bc882bb5c90fa3a1f6827eec002107c3293dccbccd955579fc31696be97c181"
|
||||
},
|
||||
"requests/06-M-fresh-V-00.json": {
|
||||
"bytes": 482,
|
||||
"sha256": "233829f2de1c9ce74e9457c701ed6eeea3d711852ed437d9067587e504f363e4"
|
||||
},
|
||||
"requests/resident-E-00.json": {
|
||||
"bytes": 362,
|
||||
"sha256": "9c941391195203054ff858f1aa53b5a17a02e40d523b397fa0b5d9350aff409a"
|
||||
},
|
||||
"requests/resident-E-01.json": {
|
||||
"bytes": 370,
|
||||
"sha256": "ee804ffb504351eeba8657803f307fefd0eb4621f7d3ce2131381df50a77f41d"
|
||||
},
|
||||
"requests/resident-E-02.json": {
|
||||
"bytes": 362,
|
||||
"sha256": "bf8f3de8033466d15e6e96f3374ae82e4186f36a13011cf9c2a87054107b17df"
|
||||
},
|
||||
"requests/resident-E-03.json": {
|
||||
"bytes": 309,
|
||||
"sha256": "b5aa4c631cd55aa124d070a0276d27c1bead9299478298a7339a63048d816488"
|
||||
},
|
||||
"requests/resident-E-04.json": {
|
||||
"bytes": 317,
|
||||
"sha256": "d498fab23ad4699c3d68ebe4e653c65ad8e83a134e58bca1f81a114ebd2d3fe4"
|
||||
},
|
||||
"requests/resident-E-05.json": {
|
||||
"bytes": 309,
|
||||
"sha256": "2672d9f8a16391d02c781143407daaa18abb72b2e0e16aa48c5426474dcfd69b"
|
||||
},
|
||||
"requests/resident-E-06.json": {
|
||||
"bytes": 362,
|
||||
"sha256": "a0405d5298cbe7b7192874d80167c63a695bebc809489030e6db8b4a7c0dad37"
|
||||
},
|
||||
"requests/resident-V-00.json": {
|
||||
"bytes": 485,
|
||||
"sha256": "c7f0f2a9fcd2a39c5d0b9e33fb147b9fade256ebc39d8fd8a130afb16977ac2c"
|
||||
},
|
||||
"requests/resident-V-01.json": {
|
||||
"bytes": 493,
|
||||
"sha256": "9fbeaa6c0a34ef520e150bc7ebd74586d092403df86e09a7ef80ca436a864cfa"
|
||||
},
|
||||
"requests/resident-V-02.json": {
|
||||
"bytes": 485,
|
||||
"sha256": "57efb661a6708697d939c4a5baaf81200b8a501550ff249a2c3fe5fa8795cb21"
|
||||
},
|
||||
"requests/resident-V-03.json": {
|
||||
"bytes": 435,
|
||||
"sha256": "7cd6601f279f58c36b4aa9e76d52a87766d156400f280a0fa760a43d5c049da2"
|
||||
},
|
||||
"requests/resident-V-04.json": {
|
||||
"bytes": 447,
|
||||
"sha256": "9e4d3f6a2f61e6956c599f9917a623ea68b93eef3aa990a849ed7db2cb42d7f0"
|
||||
},
|
||||
"requests/resident-V-05.json": {
|
||||
"bytes": 435,
|
||||
"sha256": "cd9da315302c2f962e97a511b972bb036befc8ae1b8e63f061d4f89817741c71"
|
||||
},
|
||||
"requests/resident-V-06.json": {
|
||||
"bytes": 485,
|
||||
"sha256": "39f5b6b99ea6b7e8021ab644563be8158a03257b83c8432d72a115b15b684b01"
|
||||
},
|
||||
"responses/00-M-fresh-E-00.json": {
|
||||
"bytes": 754,
|
||||
"sha256": "e0ce74fb5eabba2043ea2912bced998300159b44c47f3dd1afef27f597fbc3c2"
|
||||
},
|
||||
"responses/00-M-fresh-V-00.json": {
|
||||
"bytes": 465,
|
||||
"sha256": "482bb5ccca165daa4f4834954de20fb474e0d6c2f83fe569e252381c27840bea"
|
||||
},
|
||||
"responses/01-N-fresh-E-00.json": {
|
||||
"bytes": 755,
|
||||
"sha256": "7d4883394d3220cc258bb165f74d585f7c42f283023e06ac44782fe3e2e52db9"
|
||||
},
|
||||
"responses/01-N-fresh-V-00.json": {
|
||||
"bytes": 463,
|
||||
"sha256": "5853b2e0fdb643174d028d8e894b29282bacc1cd5225157f826170f7b28590f1"
|
||||
},
|
||||
"responses/02-M-fresh-E-00.json": {
|
||||
"bytes": 756,
|
||||
"sha256": "843c986f7bcbb82ea2cecd8b54db9b5e88cb69c9d003ad24d62e3bb8125cf299"
|
||||
},
|
||||
"responses/02-M-fresh-V-00.json": {
|
||||
"bytes": 466,
|
||||
"sha256": "39456b8335c900cc93ea59234ea7626b5430acfc40b49759c2e1a9ffc546f620"
|
||||
},
|
||||
"responses/03-N_D0-fresh-E-00.json": {
|
||||
"bytes": 754,
|
||||
"sha256": "44abfa7527a829165c960d73709b5fecbda63381a038a2e12a9a96b408545134"
|
||||
},
|
||||
"responses/03-N_D0-fresh-V-00.json": {
|
||||
"bytes": 465,
|
||||
"sha256": "36af90eff9eee027c9e9dedf6378989ef6d5f492e87cdccc6eb2e78c44b8b9f2"
|
||||
},
|
||||
"responses/04-N_frozen-fresh-E-00.json": {
|
||||
"bytes": 752,
|
||||
"sha256": "b35bb47e3bc849a460bc4ce80dc7a42963d340b868ef9972a0761e6e9c26d947"
|
||||
},
|
||||
"responses/04-N_frozen-fresh-V-00.json": {
|
||||
"bytes": 465,
|
||||
"sha256": "6b2074fc2b224b833a6ad40d84e9fc87330f399c1d69a89331db094058edaed5"
|
||||
},
|
||||
"responses/05-M_D0-fresh-E-00.json": {
|
||||
"bytes": 754,
|
||||
"sha256": "891425180e901c96419050d2a1d01686f1a071e37ace81a9ede821049016c5ae"
|
||||
},
|
||||
"responses/05-M_D0-fresh-V-00.json": {
|
||||
"bytes": 465,
|
||||
"sha256": "344f922e00d7825ea95eaf1d6c8ba2a2840d3eecace86ce9cba4fba02b46a196"
|
||||
},
|
||||
"responses/06-M-fresh-E-00.json": {
|
||||
"bytes": 754,
|
||||
"sha256": "c14c18bb55adf2a34acfc83cc92f07929573f45f8e92b9091c33e5acd8756cf9"
|
||||
},
|
||||
"responses/06-M-fresh-V-00.json": {
|
||||
"bytes": 465,
|
||||
"sha256": "1002e804c94132323afe39f1bf0b242ce7106dacc6c549f6a1f9f36ddac6fe17"
|
||||
},
|
||||
"responses/resident-E-00.json": {
|
||||
"bytes": 754,
|
||||
"sha256": "87b46dbbd6c249b764f106d9f9724b4893b117618e40d0658e5b748c36d794fd"
|
||||
},
|
||||
"responses/resident-E-01.json": {
|
||||
"bytes": 756,
|
||||
"sha256": "0344bc30e04e444251e21aad785548fb8fd6b579410821559c305c1b3153664a"
|
||||
},
|
||||
"responses/resident-E-02.json": {
|
||||
"bytes": 754,
|
||||
"sha256": "f48827fac98f48198ae0ae9e527682b5b7b46e76d0eca51bbae0bdf8cce1c26b"
|
||||
},
|
||||
"responses/resident-E-03.json": {
|
||||
"bytes": 756,
|
||||
"sha256": "deff02be73129009cd86829cdfb1c43f70b7343b76280c14097624d6fea61f41"
|
||||
},
|
||||
"responses/resident-E-04.json": {
|
||||
"bytes": 753,
|
||||
"sha256": "712219ec3bd51f98494169bc953efa4c72b3903e4a2f0ded525361af4917654d"
|
||||
},
|
||||
"responses/resident-E-05.json": {
|
||||
"bytes": 754,
|
||||
"sha256": "a35194007dae681de81e79e066f2e52f4e81847d21f88e8886f18a9e3d9d9876"
|
||||
},
|
||||
"responses/resident-E-06.json": {
|
||||
"bytes": 754,
|
||||
"sha256": "fe4f5ce8950bd560bab847ef7fe011ffa0b81b1ce2709b348ba1d8ddeec3ccab"
|
||||
},
|
||||
"responses/resident-V-00.json": {
|
||||
"bytes": 464,
|
||||
"sha256": "a8fdc9ff0882086e0ff9a2fd67b99dacf0b6eb18b5afa47c21f756b38a68bdb8"
|
||||
},
|
||||
"responses/resident-V-01.json": {
|
||||
"bytes": 465,
|
||||
"sha256": "fcc1773da52a87e6d1f558e3604d95babc9555ec5d5eaa08fcffaa878ba55967"
|
||||
},
|
||||
"responses/resident-V-02.json": {
|
||||
"bytes": 464,
|
||||
"sha256": "3eae756338c3e4a02f4033c4ffde131a234d7c8ef10ae3efc543695549bad031"
|
||||
},
|
||||
"responses/resident-V-03.json": {
|
||||
"bytes": 464,
|
||||
"sha256": "000c73862f6d2aed868e15a93861e7da0c88c40b5763cb0c999219fc93dba129"
|
||||
},
|
||||
"responses/resident-V-04.json": {
|
||||
"bytes": 463,
|
||||
"sha256": "dcd1bd45b5189fea3f9ea94cf6b4576a7bcc6552fcce6641e56f8ec5c40c4fde"
|
||||
},
|
||||
"responses/resident-V-05.json": {
|
||||
"bytes": 464,
|
||||
"sha256": "bb31eade6500f5afe5f48574fed6c1f9ee650ada98b0d479b249f9d49f1730ab"
|
||||
},
|
||||
"responses/resident-V-06.json": {
|
||||
"bytes": 464,
|
||||
"sha256": "deab50586b7a990ea759a45fde7ff2a7c1888b5d44534851d0148127726ba05d"
|
||||
},
|
||||
"updates/00-M-fresh/chain-receipt.json": {
|
||||
"bytes": 44380,
|
||||
"sha256": "e1f5d70d1f0aa41edfecc8424603ef807770b3c8097570abdc1764b851e9c305"
|
||||
},
|
||||
"updates/00-M-fresh/delta-after.npz": {
|
||||
"bytes": 31769,
|
||||
"sha256": "35b55ff715e797221163e812e4128a700eb05a4546d7f3f13dc5edc547aeb8e6"
|
||||
},
|
||||
"updates/00-M-fresh/overlay-manifest.json": {
|
||||
"bytes": 1085,
|
||||
"sha256": "60f77f30609859a718db1004e6da1c23730736285c5a1d845ec0da97385b01be"
|
||||
},
|
||||
"updates/00-M-fresh/update-receipt.json": {
|
||||
"bytes": 7608,
|
||||
"sha256": "d26c0fec7b1fcd8bbb5f7fb86b094c0870f1f0a4b29be1b3def77b66b6a3cbb5"
|
||||
},
|
||||
"updates/00-M-resident/chain-receipt.json": {
|
||||
"bytes": 44380,
|
||||
"sha256": "e1f5d70d1f0aa41edfecc8424603ef807770b3c8097570abdc1764b851e9c305"
|
||||
},
|
||||
"updates/00-M-resident/delta-after.npz": {
|
||||
"bytes": 31769,
|
||||
"sha256": "35b55ff715e797221163e812e4128a700eb05a4546d7f3f13dc5edc547aeb8e6"
|
||||
},
|
||||
"updates/00-M-resident/overlay-manifest.json": {
|
||||
"bytes": 1085,
|
||||
"sha256": "60f77f30609859a718db1004e6da1c23730736285c5a1d845ec0da97385b01be"
|
||||
},
|
||||
"updates/00-M-resident/update-receipt.json": {
|
||||
"bytes": 7608,
|
||||
"sha256": "d26c0fec7b1fcd8bbb5f7fb86b094c0870f1f0a4b29be1b3def77b66b6a3cbb5"
|
||||
},
|
||||
"updates/01-N-fresh/chain-receipt.json": {
|
||||
"bytes": 44837,
|
||||
"sha256": "c4a45ddcfea6b1800ccb6f737733b7e13b726e54e8f10e145ac6787527fffd9e"
|
||||
},
|
||||
"updates/01-N-fresh/delta-after.npz": {
|
||||
"bytes": 32463,
|
||||
"sha256": "af15c05aa9ce0fdcd2b47dcc8bef426a242f84efe7b45e79c345ff4d361d23b4"
|
||||
},
|
||||
"updates/01-N-fresh/overlay-manifest.json": {
|
||||
"bytes": 1085,
|
||||
"sha256": "a98095968f62fe7375e5acab89dbfbf55de6a28760f93dc1f5b48f238a4c54c5"
|
||||
},
|
||||
"updates/01-N-fresh/update-receipt.json": {
|
||||
"bytes": 7637,
|
||||
"sha256": "18c47fc5fceb4f1b52d601ed5114eec8239156677c44bfe364706a7e7d2fc972"
|
||||
},
|
||||
"updates/01-N-resident/chain-receipt.json": {
|
||||
"bytes": 44837,
|
||||
"sha256": "c4a45ddcfea6b1800ccb6f737733b7e13b726e54e8f10e145ac6787527fffd9e"
|
||||
},
|
||||
"updates/01-N-resident/delta-after.npz": {
|
||||
"bytes": 32463,
|
||||
"sha256": "af15c05aa9ce0fdcd2b47dcc8bef426a242f84efe7b45e79c345ff4d361d23b4"
|
||||
},
|
||||
"updates/01-N-resident/overlay-manifest.json": {
|
||||
"bytes": 1085,
|
||||
"sha256": "a98095968f62fe7375e5acab89dbfbf55de6a28760f93dc1f5b48f238a4c54c5"
|
||||
},
|
||||
"updates/01-N-resident/update-receipt.json": {
|
||||
"bytes": 7637,
|
||||
"sha256": "18c47fc5fceb4f1b52d601ed5114eec8239156677c44bfe364706a7e7d2fc972"
|
||||
},
|
||||
"updates/02-M-fresh/chain-receipt.json": {
|
||||
"bytes": 44380,
|
||||
"sha256": "e1f5d70d1f0aa41edfecc8424603ef807770b3c8097570abdc1764b851e9c305"
|
||||
},
|
||||
"updates/02-M-fresh/delta-after.npz": {
|
||||
"bytes": 31769,
|
||||
"sha256": "35b55ff715e797221163e812e4128a700eb05a4546d7f3f13dc5edc547aeb8e6"
|
||||
},
|
||||
"updates/02-M-fresh/overlay-manifest.json": {
|
||||
"bytes": 1085,
|
||||
"sha256": "60f77f30609859a718db1004e6da1c23730736285c5a1d845ec0da97385b01be"
|
||||
},
|
||||
"updates/02-M-fresh/update-receipt.json": {
|
||||
"bytes": 7608,
|
||||
"sha256": "d26c0fec7b1fcd8bbb5f7fb86b094c0870f1f0a4b29be1b3def77b66b6a3cbb5"
|
||||
},
|
||||
"updates/02-M-resident/chain-receipt.json": {
|
||||
"bytes": 44380,
|
||||
"sha256": "e1f5d70d1f0aa41edfecc8424603ef807770b3c8097570abdc1764b851e9c305"
|
||||
},
|
||||
"updates/02-M-resident/delta-after.npz": {
|
||||
"bytes": 31769,
|
||||
"sha256": "35b55ff715e797221163e812e4128a700eb05a4546d7f3f13dc5edc547aeb8e6"
|
||||
},
|
||||
"updates/02-M-resident/overlay-manifest.json": {
|
||||
"bytes": 1085,
|
||||
"sha256": "60f77f30609859a718db1004e6da1c23730736285c5a1d845ec0da97385b01be"
|
||||
},
|
||||
"updates/02-M-resident/update-receipt.json": {
|
||||
"bytes": 7608,
|
||||
"sha256": "d26c0fec7b1fcd8bbb5f7fb86b094c0870f1f0a4b29be1b3def77b66b6a3cbb5"
|
||||
},
|
||||
"updates/03-N_D0-fresh/chain-receipt.json": {
|
||||
"bytes": 44711,
|
||||
"sha256": "9869be774efc4d5ffbce36633438bd5187e9c826339c6abc2f682380a11ce531"
|
||||
},
|
||||
"updates/03-N_D0-fresh/delta-after.npz": {
|
||||
"bytes": 32303,
|
||||
"sha256": "b89e407a5d93b5f1901f901b00428dc19bd20cee2d81e57b117a2fa68d200a48"
|
||||
},
|
||||
"updates/03-N_D0-fresh/overlay-manifest.json": {
|
||||
"bytes": 1085,
|
||||
"sha256": "0d2a2aac09c75eb2729ccc1d5e6ec753f31334febbfe4f89d6bc1a9c591607d1"
|
||||
},
|
||||
"updates/03-N_D0-fresh/update-receipt.json": {
|
||||
"bytes": 7632,
|
||||
"sha256": "92181e3ca11089f7a1eba8b6e17284dec22a8786e81fe65e14adf69c7fd24aa5"
|
||||
},
|
||||
"updates/03-N_D0-resident/chain-receipt.json": {
|
||||
"bytes": 44711,
|
||||
"sha256": "9869be774efc4d5ffbce36633438bd5187e9c826339c6abc2f682380a11ce531"
|
||||
},
|
||||
"updates/03-N_D0-resident/delta-after.npz": {
|
||||
"bytes": 32303,
|
||||
"sha256": "b89e407a5d93b5f1901f901b00428dc19bd20cee2d81e57b117a2fa68d200a48"
|
||||
},
|
||||
"updates/03-N_D0-resident/overlay-manifest.json": {
|
||||
"bytes": 1085,
|
||||
"sha256": "0d2a2aac09c75eb2729ccc1d5e6ec753f31334febbfe4f89d6bc1a9c591607d1"
|
||||
},
|
||||
"updates/03-N_D0-resident/update-receipt.json": {
|
||||
"bytes": 7632,
|
||||
"sha256": "92181e3ca11089f7a1eba8b6e17284dec22a8786e81fe65e14adf69c7fd24aa5"
|
||||
},
|
||||
"updates/04-N_frozen-fresh/chain-receipt.json": {
|
||||
"bytes": 44722,
|
||||
"sha256": "53e51b4d3900e87eb40153c3dbe40e9e3f2b000bd9ac2dbba791e81d7aca04ae"
|
||||
},
|
||||
"updates/04-N_frozen-fresh/delta-after.npz": {
|
||||
"bytes": 32303,
|
||||
"sha256": "b89e407a5d93b5f1901f901b00428dc19bd20cee2d81e57b117a2fa68d200a48"
|
||||
},
|
||||
"updates/04-N_frozen-fresh/overlay-manifest.json": {
|
||||
"bytes": 1085,
|
||||
"sha256": "0d2a2aac09c75eb2729ccc1d5e6ec753f31334febbfe4f89d6bc1a9c591607d1"
|
||||
},
|
||||
"updates/04-N_frozen-fresh/update-receipt.json": {
|
||||
"bytes": 7498,
|
||||
"sha256": "545007d844de8b1717325d4cd79040907396019b1e7521219bb5b885ac224f33"
|
||||
},
|
||||
"updates/04-N_frozen-resident/chain-receipt.json": {
|
||||
"bytes": 44722,
|
||||
"sha256": "53e51b4d3900e87eb40153c3dbe40e9e3f2b000bd9ac2dbba791e81d7aca04ae"
|
||||
},
|
||||
"updates/04-N_frozen-resident/delta-after.npz": {
|
||||
"bytes": 32303,
|
||||
"sha256": "b89e407a5d93b5f1901f901b00428dc19bd20cee2d81e57b117a2fa68d200a48"
|
||||
},
|
||||
"updates/04-N_frozen-resident/overlay-manifest.json": {
|
||||
"bytes": 1085,
|
||||
"sha256": "0d2a2aac09c75eb2729ccc1d5e6ec753f31334febbfe4f89d6bc1a9c591607d1"
|
||||
},
|
||||
"updates/04-N_frozen-resident/update-receipt.json": {
|
||||
"bytes": 7498,
|
||||
"sha256": "545007d844de8b1717325d4cd79040907396019b1e7521219bb5b885ac224f33"
|
||||
},
|
||||
"updates/05-M_D0-fresh/chain-receipt.json": {
|
||||
"bytes": 44278,
|
||||
"sha256": "c374052af5c9da2084fefbaf3b874803c8dda4d4d23fd0979578ea0241e3ecfc"
|
||||
},
|
||||
"updates/05-M_D0-fresh/delta-after.npz": {
|
||||
"bytes": 31757,
|
||||
"sha256": "0b219eab09c30dc3af31fef7e6395a9bec1234090abbb72db096da833fed82c5"
|
||||
},
|
||||
"updates/05-M_D0-fresh/overlay-manifest.json": {
|
||||
"bytes": 1085,
|
||||
"sha256": "3be5d1a9d7dd1d8a580f272d3dca3616adbc157fafb4fbdfc89258719650c01e"
|
||||
},
|
||||
"updates/05-M_D0-fresh/update-receipt.json": {
|
||||
"bytes": 7591,
|
||||
"sha256": "ef8a17cbe35f973c58ae76884597100286ec0d70e987ef83b5c92add3d266312"
|
||||
},
|
||||
"updates/05-M_D0-resident/chain-receipt.json": {
|
||||
"bytes": 44278,
|
||||
"sha256": "c374052af5c9da2084fefbaf3b874803c8dda4d4d23fd0979578ea0241e3ecfc"
|
||||
},
|
||||
"updates/05-M_D0-resident/delta-after.npz": {
|
||||
"bytes": 31757,
|
||||
"sha256": "0b219eab09c30dc3af31fef7e6395a9bec1234090abbb72db096da833fed82c5"
|
||||
},
|
||||
"updates/05-M_D0-resident/overlay-manifest.json": {
|
||||
"bytes": 1085,
|
||||
"sha256": "3be5d1a9d7dd1d8a580f272d3dca3616adbc157fafb4fbdfc89258719650c01e"
|
||||
},
|
||||
"updates/05-M_D0-resident/update-receipt.json": {
|
||||
"bytes": 7591,
|
||||
"sha256": "ef8a17cbe35f973c58ae76884597100286ec0d70e987ef83b5c92add3d266312"
|
||||
},
|
||||
"updates/06-M-fresh/chain-receipt.json": {
|
||||
"bytes": 44380,
|
||||
"sha256": "e1f5d70d1f0aa41edfecc8424603ef807770b3c8097570abdc1764b851e9c305"
|
||||
},
|
||||
"updates/06-M-fresh/delta-after.npz": {
|
||||
"bytes": 31769,
|
||||
"sha256": "35b55ff715e797221163e812e4128a700eb05a4546d7f3f13dc5edc547aeb8e6"
|
||||
},
|
||||
"updates/06-M-fresh/overlay-manifest.json": {
|
||||
"bytes": 1085,
|
||||
"sha256": "60f77f30609859a718db1004e6da1c23730736285c5a1d845ec0da97385b01be"
|
||||
},
|
||||
"updates/06-M-fresh/update-receipt.json": {
|
||||
"bytes": 7608,
|
||||
"sha256": "d26c0fec7b1fcd8bbb5f7fb86b094c0870f1f0a4b29be1b3def77b66b6a3cbb5"
|
||||
},
|
||||
"updates/06-M-resident/chain-receipt.json": {
|
||||
"bytes": 44380,
|
||||
"sha256": "e1f5d70d1f0aa41edfecc8424603ef807770b3c8097570abdc1764b851e9c305"
|
||||
},
|
||||
"updates/06-M-resident/delta-after.npz": {
|
||||
"bytes": 31769,
|
||||
"sha256": "35b55ff715e797221163e812e4128a700eb05a4546d7f3f13dc5edc547aeb8e6"
|
||||
},
|
||||
"updates/06-M-resident/overlay-manifest.json": {
|
||||
"bytes": 1085,
|
||||
"sha256": "60f77f30609859a718db1004e6da1c23730736285c5a1d845ec0da97385b01be"
|
||||
},
|
||||
"updates/06-M-resident/update-receipt.json": {
|
||||
"bytes": 7608,
|
||||
"sha256": "d26c0fec7b1fcd8bbb5f7fb86b094c0870f1f0a4b29be1b3def77b66b6a3cbb5"
|
||||
},
|
||||
"validation/00-M-fresh.json": {
|
||||
"bytes": 1865,
|
||||
"sha256": "be69678fb053f0904cd118bc5acdc09085cb780a1997c9a18b9d9661c5922d82"
|
||||
},
|
||||
"validation/00-M-resident.json": {
|
||||
"bytes": 2229,
|
||||
"sha256": "4314d615874a8d8da77655a0125c7feb6138df0bc85c0686e94496b96a4a3459"
|
||||
},
|
||||
"validation/01-N-fresh.json": {
|
||||
"bytes": 1865,
|
||||
"sha256": "b8f4a419a55f8b057973a2e2f1e97d7869200831852b5f05e97ca10f036e5363"
|
||||
},
|
||||
"validation/01-N-resident.json": {
|
||||
"bytes": 2229,
|
||||
"sha256": "dbadc825f3d52fba6331529dda7ea613931e24977379a87ab91aba669cc9a227"
|
||||
},
|
||||
"validation/02-M-fresh.json": {
|
||||
"bytes": 1865,
|
||||
"sha256": "be69678fb053f0904cd118bc5acdc09085cb780a1997c9a18b9d9661c5922d82"
|
||||
},
|
||||
"validation/02-M-resident.json": {
|
||||
"bytes": 2229,
|
||||
"sha256": "4314d615874a8d8da77655a0125c7feb6138df0bc85c0686e94496b96a4a3459"
|
||||
},
|
||||
"validation/03-N_D0-fresh.json": {
|
||||
"bytes": 1865,
|
||||
"sha256": "375a56ec0d3cff73190778dee6babae9f531e4b94e489024cb3aabc8c3b1b81b"
|
||||
},
|
||||
"validation/03-N_D0-resident.json": {
|
||||
"bytes": 2229,
|
||||
"sha256": "559b70274970dd45ed5fe7e80afe5b9ee8462e9f01eae5a9bcc4de8d5ae87b0a"
|
||||
},
|
||||
"validation/04-N_frozen-fresh.json": {
|
||||
"bytes": 1865,
|
||||
"sha256": "3a1b503977351da83617dbef8d3282df78a1d1525e02de6b9c2b5f11103d8692"
|
||||
},
|
||||
"validation/04-N_frozen-resident.json": {
|
||||
"bytes": 2229,
|
||||
"sha256": "fc21354854418cd0418ca6cf93400355e670ebec8f6964d332bf572e57e7afbf"
|
||||
},
|
||||
"validation/05-M_D0-fresh.json": {
|
||||
"bytes": 1865,
|
||||
"sha256": "21ff335bd8f1ac9c92d98e153183978970dd55efa0ca90c530407238b25598fa"
|
||||
},
|
||||
"validation/05-M_D0-resident.json": {
|
||||
"bytes": 2229,
|
||||
"sha256": "dbedc16911deab6116e3db5cb9422329409b4a9e982d027367e4f11f9ef22415"
|
||||
},
|
||||
"validation/06-M-fresh.json": {
|
||||
"bytes": 1865,
|
||||
"sha256": "be69678fb053f0904cd118bc5acdc09085cb780a1997c9a18b9d9661c5922d82"
|
||||
},
|
||||
"validation/06-M-resident.json": {
|
||||
"bytes": 2229,
|
||||
"sha256": "4314d615874a8d8da77655a0125c7feb6138df0bc85c0686e94496b96a4a3459"
|
||||
}
|
||||
},
|
||||
"manifest_self_excluded": true
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"actual_parent_observed_exit": 0,
|
||||
"argv": [
|
||||
"/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||
"-B",
|
||||
"/data/digital-drosophila/tools/conditioning-perf-lab-v1/perf_probe.py",
|
||||
"worker",
|
||||
"--role",
|
||||
"update",
|
||||
"--mode",
|
||||
"once",
|
||||
"--plan",
|
||||
"/tmp/malecns-cpu-residency-woqIQa/benchmark-plan.json",
|
||||
"--plan-sha",
|
||||
"ad9b906f90eb742706acc4cfe676a845900ad850f2482d0e8fb42d8faf3d71d1"
|
||||
],
|
||||
"lifetime_parent_seconds": 4.8041809019996435,
|
||||
"mode": "once",
|
||||
"pid": 735421,
|
||||
"role": "update",
|
||||
"startup_seconds": 0.03941856900200946,
|
||||
"stderr_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"task_ACKs_are_not_individual_OS_exits": true,
|
||||
"tasks_acknowledged": 1
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"actual_parent_observed_exit": 0,
|
||||
"argv": [
|
||||
"/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||
"-B",
|
||||
"/data/digital-drosophila/tools/conditioning-perf-lab-v1/perf_probe.py",
|
||||
"worker",
|
||||
"--role",
|
||||
"verify-reference",
|
||||
"--mode",
|
||||
"once",
|
||||
"--plan",
|
||||
"/tmp/malecns-cpu-residency-woqIQa/benchmark-plan.json",
|
||||
"--plan-sha",
|
||||
"ad9b906f90eb742706acc4cfe676a845900ad850f2482d0e8fb42d8faf3d71d1"
|
||||
],
|
||||
"lifetime_parent_seconds": 4.153049107000697,
|
||||
"mode": "once",
|
||||
"pid": 735682,
|
||||
"role": "verify-reference",
|
||||
"startup_seconds": 0.03956143800314749,
|
||||
"stderr_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"task_ACKs_are_not_individual_OS_exits": true,
|
||||
"tasks_acknowledged": 1
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"actual_parent_observed_exit": 0,
|
||||
"argv": [
|
||||
"/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||
"-B",
|
||||
"/data/digital-drosophila/tools/conditioning-perf-lab-v1/perf_probe.py",
|
||||
"worker",
|
||||
"--role",
|
||||
"update",
|
||||
"--mode",
|
||||
"once",
|
||||
"--plan",
|
||||
"/tmp/malecns-cpu-residency-woqIQa/benchmark-plan.json",
|
||||
"--plan-sha",
|
||||
"ad9b906f90eb742706acc4cfe676a845900ad850f2482d0e8fb42d8faf3d71d1"
|
||||
],
|
||||
"lifetime_parent_seconds": 4.551296638994245,
|
||||
"mode": "once",
|
||||
"pid": 735877,
|
||||
"role": "update",
|
||||
"startup_seconds": 0.041211482996004634,
|
||||
"stderr_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"task_ACKs_are_not_individual_OS_exits": true,
|
||||
"tasks_acknowledged": 1
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"actual_parent_observed_exit": 0,
|
||||
"argv": [
|
||||
"/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||
"-B",
|
||||
"/data/digital-drosophila/tools/conditioning-perf-lab-v1/perf_probe.py",
|
||||
"worker",
|
||||
"--role",
|
||||
"verify-reference",
|
||||
"--mode",
|
||||
"once",
|
||||
"--plan",
|
||||
"/tmp/malecns-cpu-residency-woqIQa/benchmark-plan.json",
|
||||
"--plan-sha",
|
||||
"ad9b906f90eb742706acc4cfe676a845900ad850f2482d0e8fb42d8faf3d71d1"
|
||||
],
|
||||
"lifetime_parent_seconds": 3.902626559000055,
|
||||
"mode": "once",
|
||||
"pid": 736079,
|
||||
"role": "verify-reference",
|
||||
"startup_seconds": 0.04110846600087825,
|
||||
"stderr_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"task_ACKs_are_not_individual_OS_exits": true,
|
||||
"tasks_acknowledged": 1
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"actual_parent_observed_exit": 0,
|
||||
"argv": [
|
||||
"/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||
"-B",
|
||||
"/data/digital-drosophila/tools/conditioning-perf-lab-v1/perf_probe.py",
|
||||
"worker",
|
||||
"--role",
|
||||
"update",
|
||||
"--mode",
|
||||
"once",
|
||||
"--plan",
|
||||
"/tmp/malecns-cpu-residency-woqIQa/benchmark-plan.json",
|
||||
"--plan-sha",
|
||||
"ad9b906f90eb742706acc4cfe676a845900ad850f2482d0e8fb42d8faf3d71d1"
|
||||
],
|
||||
"lifetime_parent_seconds": 4.735514142004831,
|
||||
"mode": "once",
|
||||
"pid": 736147,
|
||||
"role": "update",
|
||||
"startup_seconds": 0.04088733500248054,
|
||||
"stderr_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"task_ACKs_are_not_individual_OS_exits": true,
|
||||
"tasks_acknowledged": 1
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"actual_parent_observed_exit": 0,
|
||||
"argv": [
|
||||
"/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||
"-B",
|
||||
"/data/digital-drosophila/tools/conditioning-perf-lab-v1/perf_probe.py",
|
||||
"worker",
|
||||
"--role",
|
||||
"verify-reference",
|
||||
"--mode",
|
||||
"once",
|
||||
"--plan",
|
||||
"/tmp/malecns-cpu-residency-woqIQa/benchmark-plan.json",
|
||||
"--plan-sha",
|
||||
"ad9b906f90eb742706acc4cfe676a845900ad850f2482d0e8fb42d8faf3d71d1"
|
||||
],
|
||||
"lifetime_parent_seconds": 4.103694833996997,
|
||||
"mode": "once",
|
||||
"pid": 736341,
|
||||
"role": "verify-reference",
|
||||
"startup_seconds": 0.04011784899921622,
|
||||
"stderr_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"task_ACKs_are_not_individual_OS_exits": true,
|
||||
"tasks_acknowledged": 1
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"actual_parent_observed_exit": 0,
|
||||
"argv": [
|
||||
"/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||
"-B",
|
||||
"/data/digital-drosophila/tools/conditioning-perf-lab-v1/perf_probe.py",
|
||||
"worker",
|
||||
"--role",
|
||||
"update",
|
||||
"--mode",
|
||||
"once",
|
||||
"--plan",
|
||||
"/tmp/malecns-cpu-residency-woqIQa/benchmark-plan.json",
|
||||
"--plan-sha",
|
||||
"ad9b906f90eb742706acc4cfe676a845900ad850f2482d0e8fb42d8faf3d71d1"
|
||||
],
|
||||
"lifetime_parent_seconds": 4.5949991710003815,
|
||||
"mode": "once",
|
||||
"pid": 736537,
|
||||
"role": "update",
|
||||
"startup_seconds": 0.04200840900011826,
|
||||
"stderr_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"task_ACKs_are_not_individual_OS_exits": true,
|
||||
"tasks_acknowledged": 1
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"actual_parent_observed_exit": 0,
|
||||
"argv": [
|
||||
"/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||
"-B",
|
||||
"/data/digital-drosophila/tools/conditioning-perf-lab-v1/perf_probe.py",
|
||||
"worker",
|
||||
"--role",
|
||||
"verify-reference",
|
||||
"--mode",
|
||||
"once",
|
||||
"--plan",
|
||||
"/tmp/malecns-cpu-residency-woqIQa/benchmark-plan.json",
|
||||
"--plan-sha",
|
||||
"ad9b906f90eb742706acc4cfe676a845900ad850f2482d0e8fb42d8faf3d71d1"
|
||||
],
|
||||
"lifetime_parent_seconds": 3.924993649998214,
|
||||
"mode": "once",
|
||||
"pid": 736675,
|
||||
"role": "verify-reference",
|
||||
"startup_seconds": 0.041427705000387505,
|
||||
"stderr_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"task_ACKs_are_not_individual_OS_exits": true,
|
||||
"tasks_acknowledged": 1
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"actual_parent_observed_exit": 0,
|
||||
"argv": [
|
||||
"/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||
"-B",
|
||||
"/data/digital-drosophila/tools/conditioning-perf-lab-v1/perf_probe.py",
|
||||
"worker",
|
||||
"--role",
|
||||
"update",
|
||||
"--mode",
|
||||
"once",
|
||||
"--plan",
|
||||
"/tmp/malecns-cpu-residency-woqIQa/benchmark-plan.json",
|
||||
"--plan-sha",
|
||||
"ad9b906f90eb742706acc4cfe676a845900ad850f2482d0e8fb42d8faf3d71d1"
|
||||
],
|
||||
"lifetime_parent_seconds": 4.620397169004718,
|
||||
"mode": "once",
|
||||
"pid": 736869,
|
||||
"role": "update",
|
||||
"startup_seconds": 0.04003098099929048,
|
||||
"stderr_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"task_ACKs_are_not_individual_OS_exits": true,
|
||||
"tasks_acknowledged": 1
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"actual_parent_observed_exit": 0,
|
||||
"argv": [
|
||||
"/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||
"-B",
|
||||
"/data/digital-drosophila/tools/conditioning-perf-lab-v1/perf_probe.py",
|
||||
"worker",
|
||||
"--role",
|
||||
"verify-reference",
|
||||
"--mode",
|
||||
"once",
|
||||
"--plan",
|
||||
"/tmp/malecns-cpu-residency-woqIQa/benchmark-plan.json",
|
||||
"--plan-sha",
|
||||
"ad9b906f90eb742706acc4cfe676a845900ad850f2482d0e8fb42d8faf3d71d1"
|
||||
],
|
||||
"lifetime_parent_seconds": 3.9045120619994123,
|
||||
"mode": "once",
|
||||
"pid": 737063,
|
||||
"role": "verify-reference",
|
||||
"startup_seconds": 0.04213572099979501,
|
||||
"stderr_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"task_ACKs_are_not_individual_OS_exits": true,
|
||||
"tasks_acknowledged": 1
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"actual_parent_observed_exit": 0,
|
||||
"argv": [
|
||||
"/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||
"-B",
|
||||
"/data/digital-drosophila/tools/conditioning-perf-lab-v1/perf_probe.py",
|
||||
"worker",
|
||||
"--role",
|
||||
"update",
|
||||
"--mode",
|
||||
"once",
|
||||
"--plan",
|
||||
"/tmp/malecns-cpu-residency-woqIQa/benchmark-plan.json",
|
||||
"--plan-sha",
|
||||
"ad9b906f90eb742706acc4cfe676a845900ad850f2482d0e8fb42d8faf3d71d1"
|
||||
],
|
||||
"lifetime_parent_seconds": 4.764637047999713,
|
||||
"mode": "once",
|
||||
"pid": 737285,
|
||||
"role": "update",
|
||||
"startup_seconds": 0.04027060599764809,
|
||||
"stderr_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"task_ACKs_are_not_individual_OS_exits": true,
|
||||
"tasks_acknowledged": 1
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"actual_parent_observed_exit": 0,
|
||||
"argv": [
|
||||
"/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||
"-B",
|
||||
"/data/digital-drosophila/tools/conditioning-perf-lab-v1/perf_probe.py",
|
||||
"worker",
|
||||
"--role",
|
||||
"verify-reference",
|
||||
"--mode",
|
||||
"once",
|
||||
"--plan",
|
||||
"/tmp/malecns-cpu-residency-woqIQa/benchmark-plan.json",
|
||||
"--plan-sha",
|
||||
"ad9b906f90eb742706acc4cfe676a845900ad850f2482d0e8fb42d8faf3d71d1"
|
||||
],
|
||||
"lifetime_parent_seconds": 4.06785895700159,
|
||||
"mode": "once",
|
||||
"pid": 737398,
|
||||
"role": "verify-reference",
|
||||
"startup_seconds": 0.04107048700097948,
|
||||
"stderr_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"task_ACKs_are_not_individual_OS_exits": true,
|
||||
"tasks_acknowledged": 1
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"actual_parent_observed_exit": 0,
|
||||
"argv": [
|
||||
"/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||
"-B",
|
||||
"/data/digital-drosophila/tools/conditioning-perf-lab-v1/perf_probe.py",
|
||||
"worker",
|
||||
"--role",
|
||||
"update",
|
||||
"--mode",
|
||||
"once",
|
||||
"--plan",
|
||||
"/tmp/malecns-cpu-residency-woqIQa/benchmark-plan.json",
|
||||
"--plan-sha",
|
||||
"ad9b906f90eb742706acc4cfe676a845900ad850f2482d0e8fb42d8faf3d71d1"
|
||||
],
|
||||
"lifetime_parent_seconds": 4.7666301089993794,
|
||||
"mode": "once",
|
||||
"pid": 737528,
|
||||
"role": "update",
|
||||
"startup_seconds": 0.04145412399520865,
|
||||
"stderr_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"task_ACKs_are_not_individual_OS_exits": true,
|
||||
"tasks_acknowledged": 1
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"actual_parent_observed_exit": 0,
|
||||
"argv": [
|
||||
"/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||
"-B",
|
||||
"/data/digital-drosophila/tools/conditioning-perf-lab-v1/perf_probe.py",
|
||||
"worker",
|
||||
"--role",
|
||||
"verify-reference",
|
||||
"--mode",
|
||||
"once",
|
||||
"--plan",
|
||||
"/tmp/malecns-cpu-residency-woqIQa/benchmark-plan.json",
|
||||
"--plan-sha",
|
||||
"ad9b906f90eb742706acc4cfe676a845900ad850f2482d0e8fb42d8faf3d71d1"
|
||||
],
|
||||
"lifetime_parent_seconds": 4.0638777050044155,
|
||||
"mode": "once",
|
||||
"pid": 737791,
|
||||
"role": "verify-reference",
|
||||
"startup_seconds": 0.04130304000136675,
|
||||
"stderr_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"task_ACKs_are_not_individual_OS_exits": true,
|
||||
"tasks_acknowledged": 1
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"actual_parent_observed_exit": 0,
|
||||
"argv": [
|
||||
"/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||
"-B",
|
||||
"/data/digital-drosophila/tools/conditioning-perf-lab-v1/perf_probe.py",
|
||||
"worker",
|
||||
"--role",
|
||||
"update",
|
||||
"--mode",
|
||||
"server",
|
||||
"--plan",
|
||||
"/tmp/malecns-cpu-residency-woqIQa/benchmark-plan.json",
|
||||
"--plan-sha",
|
||||
"ad9b906f90eb742706acc4cfe676a845900ad850f2482d0e8fb42d8faf3d71d1"
|
||||
],
|
||||
"lifetime_parent_seconds": 98.41863379300048,
|
||||
"mode": "server",
|
||||
"pid": 735419,
|
||||
"role": "update",
|
||||
"startup_seconds": 0.040455851005390286,
|
||||
"stderr_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"task_ACKs_are_not_individual_OS_exits": true,
|
||||
"tasks_acknowledged": 7
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"actual_parent_observed_exit": 0,
|
||||
"argv": [
|
||||
"/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||
"-B",
|
||||
"/data/digital-drosophila/tools/conditioning-perf-lab-v1/perf_probe.py",
|
||||
"worker",
|
||||
"--role",
|
||||
"verify-resident",
|
||||
"--mode",
|
||||
"server",
|
||||
"--plan",
|
||||
"/tmp/malecns-cpu-residency-woqIQa/benchmark-plan.json",
|
||||
"--plan-sha",
|
||||
"ad9b906f90eb742706acc4cfe676a845900ad850f2482d0e8fb42d8faf3d71d1"
|
||||
],
|
||||
"lifetime_parent_seconds": 98.74351359399589,
|
||||
"mode": "server",
|
||||
"pid": 735420,
|
||||
"role": "verify-resident",
|
||||
"startup_seconds": 0.04034673299611313,
|
||||
"stderr_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"task_ACKs_are_not_individual_OS_exits": true,
|
||||
"tasks_acknowledged": 7
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
{
|
||||
"AR_modified": false,
|
||||
"GPU_benchmarked": false,
|
||||
"brain_run": false,
|
||||
"candidate_generated": false,
|
||||
"end_to_end_AR_speedup_not_measured": true,
|
||||
"full_history_reaudit": false,
|
||||
"learning_test": false,
|
||||
"prototype_plan_sha256": "ad9b906f90eb742706acc4cfe676a845900ad850f2482d0e8fb42d8faf3d71d1",
|
||||
"resident_process_exits": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"scope": "7 fixed engineering replays; CPU postprocessing only. Not authorized or validated as AR replacement.",
|
||||
"source_and_consumed_input_SHA_unchanged": true,
|
||||
"static_hash_cache_removed": false,
|
||||
"status": "PASS-CPU-RESIDENCY-PROTOTYPE-ONLY",
|
||||
"timing": {
|
||||
"fresh_E_seconds": {
|
||||
"all_mean": 4.691093597143273,
|
||||
"warm_mean": 4.672245713000545,
|
||||
"warm_median": 4.677955655504775
|
||||
},
|
||||
"fresh_V_seconds": {
|
||||
"all_mean": 4.017230410571626,
|
||||
"warm_mean": 3.9945939611667804,
|
||||
"warm_median": 3.994435677501315
|
||||
},
|
||||
"resident_E_seconds": {
|
||||
"all_mean": 2.9867054258585477,
|
||||
"warm_mean": 2.7626112083344196,
|
||||
"warm_median": 2.7719067460020597
|
||||
},
|
||||
"resident_V_seconds": {
|
||||
"all_mean": 2.28122039428646,
|
||||
"warm_mean": 2.063014349333874,
|
||||
"warm_median": 2.0714335105003556
|
||||
},
|
||||
"warm_E_only_with_original_fresh_verifier_speedup_ratio": 1.2826071514426267,
|
||||
"warm_combined_speedup_ratio": 1.7960033513986688
|
||||
},
|
||||
"timing_boundary": "Parent request includes input/chain digest, request+response persistence and output verification. Fresh also includes spawn/ready/exit; resident lifetime/startup separately recorded.",
|
||||
"total_wall_seconds": 100.45934602300258,
|
||||
"trials": [
|
||||
{
|
||||
"fresh_E_seconds": 4.8041809019996435,
|
||||
"fresh_V_seconds": 4.153049107000697,
|
||||
"label": "M",
|
||||
"original_fresh_validator_actual_exit": 0,
|
||||
"position": 0,
|
||||
"resident_E_seconds": 4.331270731003315,
|
||||
"resident_V_seconds": 3.5904566640019766,
|
||||
"update_comparison": {
|
||||
"all_four_files_SHA_identical": true,
|
||||
"arrays_bitwise_identical": true,
|
||||
"full_update_receipt_and_trace_digests_identical": true
|
||||
},
|
||||
"validator_comparison": {
|
||||
"all_scientific_fields_identical": true,
|
||||
"explicit_differing_fields": [
|
||||
"schema",
|
||||
"validator_source",
|
||||
"original_validator_source",
|
||||
"resident_prototype",
|
||||
"resident_cache_scope"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"fresh_E_seconds": 4.551296638994245,
|
||||
"fresh_V_seconds": 3.902626559000055,
|
||||
"label": "N",
|
||||
"original_fresh_validator_actual_exit": 0,
|
||||
"position": 1,
|
||||
"resident_E_seconds": 2.678891448005743,
|
||||
"resident_V_seconds": 2.062450468001771,
|
||||
"update_comparison": {
|
||||
"all_four_files_SHA_identical": true,
|
||||
"arrays_bitwise_identical": true,
|
||||
"full_update_receipt_and_trace_digests_identical": true
|
||||
},
|
||||
"validator_comparison": {
|
||||
"all_scientific_fields_identical": true,
|
||||
"explicit_differing_fields": [
|
||||
"schema",
|
||||
"validator_source",
|
||||
"original_validator_source",
|
||||
"resident_prototype",
|
||||
"resident_cache_scope"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"fresh_E_seconds": 4.735514142004831,
|
||||
"fresh_V_seconds": 4.103694833996997,
|
||||
"label": "M",
|
||||
"original_fresh_validator_actual_exit": 0,
|
||||
"position": 2,
|
||||
"resident_E_seconds": 2.857203049999953,
|
||||
"resident_V_seconds": 2.14666489699448,
|
||||
"update_comparison": {
|
||||
"all_four_files_SHA_identical": true,
|
||||
"arrays_bitwise_identical": true,
|
||||
"full_update_receipt_and_trace_digests_identical": true
|
||||
},
|
||||
"validator_comparison": {
|
||||
"all_scientific_fields_identical": true,
|
||||
"explicit_differing_fields": [
|
||||
"schema",
|
||||
"validator_source",
|
||||
"original_validator_source",
|
||||
"resident_prototype",
|
||||
"resident_cache_scope"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"fresh_E_seconds": 4.5949991710003815,
|
||||
"fresh_V_seconds": 3.924993649998214,
|
||||
"label": "N_D0",
|
||||
"original_fresh_validator_actual_exit": 0,
|
||||
"position": 3,
|
||||
"resident_E_seconds": 2.6922046239997144,
|
||||
"resident_V_seconds": 1.9751014260036754,
|
||||
"update_comparison": {
|
||||
"all_four_files_SHA_identical": true,
|
||||
"arrays_bitwise_identical": true,
|
||||
"full_update_receipt_and_trace_digests_identical": true
|
||||
},
|
||||
"validator_comparison": {
|
||||
"all_scientific_fields_identical": true,
|
||||
"explicit_differing_fields": [
|
||||
"schema",
|
||||
"validator_source",
|
||||
"original_validator_source",
|
||||
"resident_prototype",
|
||||
"resident_cache_scope"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"fresh_E_seconds": 4.620397169004718,
|
||||
"fresh_V_seconds": 3.9045120619994123,
|
||||
"label": "N_frozen",
|
||||
"original_fresh_validator_actual_exit": 0,
|
||||
"position": 4,
|
||||
"resident_E_seconds": 2.7464958280033898,
|
||||
"resident_V_seconds": 2.027457176001917,
|
||||
"update_comparison": {
|
||||
"all_four_files_SHA_identical": true,
|
||||
"arrays_bitwise_identical": true,
|
||||
"full_update_receipt_and_trace_digests_identical": true
|
||||
},
|
||||
"validator_comparison": {
|
||||
"all_scientific_fields_identical": true,
|
||||
"explicit_differing_fields": [
|
||||
"schema",
|
||||
"validator_source",
|
||||
"original_validator_source",
|
||||
"resident_prototype",
|
||||
"resident_cache_scope"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"fresh_E_seconds": 4.764637047999713,
|
||||
"fresh_V_seconds": 4.06785895700159,
|
||||
"label": "M_D0",
|
||||
"original_fresh_validator_actual_exit": 0,
|
||||
"position": 5,
|
||||
"resident_E_seconds": 2.7973176640007296,
|
||||
"resident_V_seconds": 2.0859955760024604,
|
||||
"update_comparison": {
|
||||
"all_four_files_SHA_identical": true,
|
||||
"arrays_bitwise_identical": true,
|
||||
"full_update_receipt_and_trace_digests_identical": true
|
||||
},
|
||||
"validator_comparison": {
|
||||
"all_scientific_fields_identical": true,
|
||||
"explicit_differing_fields": [
|
||||
"schema",
|
||||
"validator_source",
|
||||
"original_validator_source",
|
||||
"resident_prototype",
|
||||
"resident_cache_scope"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"fresh_E_seconds": 4.7666301089993794,
|
||||
"fresh_V_seconds": 4.0638777050044155,
|
||||
"label": "M",
|
||||
"original_fresh_validator_actual_exit": 0,
|
||||
"position": 6,
|
||||
"resident_E_seconds": 2.8035546359969885,
|
||||
"resident_V_seconds": 2.0804165529989405,
|
||||
"update_comparison": {
|
||||
"all_four_files_SHA_identical": true,
|
||||
"arrays_bitwise_identical": true,
|
||||
"full_update_receipt_and_trace_digests_identical": true
|
||||
},
|
||||
"validator_comparison": {
|
||||
"all_scientific_fields_identical": true,
|
||||
"explicit_differing_fields": [
|
||||
"schema",
|
||||
"validator_source",
|
||||
"original_validator_source",
|
||||
"resident_prototype",
|
||||
"resident_cache_scope"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"authority": "/data/digital-drosophila/experiments/phase4aq-conditioning-execution/authorities/mechanical--fresh-parent.epoch.json",
|
||||
"authority_sha256": "4616a42c255ab839346368aa0e5e4306bb3878e55fcc95b176f058b1993c9b0c",
|
||||
"chain_sha256": null,
|
||||
"output": "/tmp/malecns-cpu-residency-woqIQa/updates/00-M-fresh",
|
||||
"sequence": 0,
|
||||
"update_dir": null
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"authority": "/data/digital-drosophila/experiments/phase4aq-conditioning-execution/authorities/mechanical--fresh-parent.epoch.json",
|
||||
"authority_sha256": "4616a42c255ab839346368aa0e5e4306bb3878e55fcc95b176f058b1993c9b0c",
|
||||
"chain_sha256": "e1f5d70d1f0aa41edfecc8424603ef807770b3c8097570abdc1764b851e9c305",
|
||||
"output": "/tmp/malecns-cpu-residency-woqIQa/validation/00-M-fresh.json",
|
||||
"sequence": 0,
|
||||
"update_dir": "/tmp/malecns-cpu-residency-woqIQa/updates/00-M-resident"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"authority": "/data/digital-drosophila/experiments/phase4aq-conditioning-execution/authorities/performance--natural-light-fresh.epoch.json",
|
||||
"authority_sha256": "785e3d26d06b47efe7f054883d38fe2e13711195359bf9f4b03aa88887fbfb37",
|
||||
"chain_sha256": null,
|
||||
"output": "/tmp/malecns-cpu-residency-woqIQa/updates/01-N-fresh",
|
||||
"sequence": 0,
|
||||
"update_dir": null
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"authority": "/data/digital-drosophila/experiments/phase4aq-conditioning-execution/authorities/performance--natural-light-fresh.epoch.json",
|
||||
"authority_sha256": "785e3d26d06b47efe7f054883d38fe2e13711195359bf9f4b03aa88887fbfb37",
|
||||
"chain_sha256": "c4a45ddcfea6b1800ccb6f737733b7e13b726e54e8f10e145ac6787527fffd9e",
|
||||
"output": "/tmp/malecns-cpu-residency-woqIQa/validation/01-N-fresh.json",
|
||||
"sequence": 0,
|
||||
"update_dir": "/tmp/malecns-cpu-residency-woqIQa/updates/01-N-resident"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"authority": "/data/digital-drosophila/experiments/phase4aq-conditioning-execution/authorities/mechanical--fresh-parent.epoch.json",
|
||||
"authority_sha256": "4616a42c255ab839346368aa0e5e4306bb3878e55fcc95b176f058b1993c9b0c",
|
||||
"chain_sha256": null,
|
||||
"output": "/tmp/malecns-cpu-residency-woqIQa/updates/02-M-fresh",
|
||||
"sequence": 0,
|
||||
"update_dir": null
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"authority": "/data/digital-drosophila/experiments/phase4aq-conditioning-execution/authorities/mechanical--fresh-parent.epoch.json",
|
||||
"authority_sha256": "4616a42c255ab839346368aa0e5e4306bb3878e55fcc95b176f058b1993c9b0c",
|
||||
"chain_sha256": "e1f5d70d1f0aa41edfecc8424603ef807770b3c8097570abdc1764b851e9c305",
|
||||
"output": "/tmp/malecns-cpu-residency-woqIQa/validation/02-M-fresh.json",
|
||||
"sequence": 0,
|
||||
"update_dir": "/tmp/malecns-cpu-residency-woqIQa/updates/02-M-resident"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"authority": "/tmp/malecns-cpu-residency-woqIQa/inputs/N_D0.authority.json",
|
||||
"authority_sha256": "4a7ee78ca0671efa0cb5203f7ba405ae3a53b3e23ebfcb8bf52887ce20c0f40b",
|
||||
"chain_sha256": null,
|
||||
"output": "/tmp/malecns-cpu-residency-woqIQa/updates/03-N_D0-fresh",
|
||||
"sequence": 0,
|
||||
"update_dir": null
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"authority": "/tmp/malecns-cpu-residency-woqIQa/inputs/N_D0.authority.json",
|
||||
"authority_sha256": "4a7ee78ca0671efa0cb5203f7ba405ae3a53b3e23ebfcb8bf52887ce20c0f40b",
|
||||
"chain_sha256": "9869be774efc4d5ffbce36633438bd5187e9c826339c6abc2f682380a11ce531",
|
||||
"output": "/tmp/malecns-cpu-residency-woqIQa/validation/03-N_D0-fresh.json",
|
||||
"sequence": 0,
|
||||
"update_dir": "/tmp/malecns-cpu-residency-woqIQa/updates/03-N_D0-resident"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"authority": "/tmp/malecns-cpu-residency-woqIQa/inputs/N_frozen.authority.json",
|
||||
"authority_sha256": "3063f74a5dbbfb6afa92ee7692bbb0626017b0451072b838be2f9e0bc58748e3",
|
||||
"chain_sha256": null,
|
||||
"output": "/tmp/malecns-cpu-residency-woqIQa/updates/04-N_frozen-fresh",
|
||||
"sequence": 0,
|
||||
"update_dir": null
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"authority": "/tmp/malecns-cpu-residency-woqIQa/inputs/N_frozen.authority.json",
|
||||
"authority_sha256": "3063f74a5dbbfb6afa92ee7692bbb0626017b0451072b838be2f9e0bc58748e3",
|
||||
"chain_sha256": "53e51b4d3900e87eb40153c3dbe40e9e3f2b000bd9ac2dbba791e81d7aca04ae",
|
||||
"output": "/tmp/malecns-cpu-residency-woqIQa/validation/04-N_frozen-fresh.json",
|
||||
"sequence": 0,
|
||||
"update_dir": "/tmp/malecns-cpu-residency-woqIQa/updates/04-N_frozen-resident"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"authority": "/tmp/malecns-cpu-residency-woqIQa/inputs/M_D0.authority.json",
|
||||
"authority_sha256": "56d89454417c4c7d8e4dd1dc3437ad0df55ded706b9e603681bbf491338cbf04",
|
||||
"chain_sha256": null,
|
||||
"output": "/tmp/malecns-cpu-residency-woqIQa/updates/05-M_D0-fresh",
|
||||
"sequence": 0,
|
||||
"update_dir": null
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"authority": "/tmp/malecns-cpu-residency-woqIQa/inputs/M_D0.authority.json",
|
||||
"authority_sha256": "56d89454417c4c7d8e4dd1dc3437ad0df55ded706b9e603681bbf491338cbf04",
|
||||
"chain_sha256": "c374052af5c9da2084fefbaf3b874803c8dda4d4d23fd0979578ea0241e3ecfc",
|
||||
"output": "/tmp/malecns-cpu-residency-woqIQa/validation/05-M_D0-fresh.json",
|
||||
"sequence": 0,
|
||||
"update_dir": "/tmp/malecns-cpu-residency-woqIQa/updates/05-M_D0-resident"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"authority": "/data/digital-drosophila/experiments/phase4aq-conditioning-execution/authorities/mechanical--fresh-parent.epoch.json",
|
||||
"authority_sha256": "4616a42c255ab839346368aa0e5e4306bb3878e55fcc95b176f058b1993c9b0c",
|
||||
"chain_sha256": null,
|
||||
"output": "/tmp/malecns-cpu-residency-woqIQa/updates/06-M-fresh",
|
||||
"sequence": 0,
|
||||
"update_dir": null
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"authority": "/data/digital-drosophila/experiments/phase4aq-conditioning-execution/authorities/mechanical--fresh-parent.epoch.json",
|
||||
"authority_sha256": "4616a42c255ab839346368aa0e5e4306bb3878e55fcc95b176f058b1993c9b0c",
|
||||
"chain_sha256": "e1f5d70d1f0aa41edfecc8424603ef807770b3c8097570abdc1764b851e9c305",
|
||||
"output": "/tmp/malecns-cpu-residency-woqIQa/validation/06-M-fresh.json",
|
||||
"sequence": 0,
|
||||
"update_dir": "/tmp/malecns-cpu-residency-woqIQa/updates/06-M-resident"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"authority": "/data/digital-drosophila/experiments/phase4aq-conditioning-execution/authorities/mechanical--fresh-parent.epoch.json",
|
||||
"authority_sha256": "4616a42c255ab839346368aa0e5e4306bb3878e55fcc95b176f058b1993c9b0c",
|
||||
"chain_sha256": null,
|
||||
"output": "/tmp/malecns-cpu-residency-woqIQa/updates/00-M-resident",
|
||||
"sequence": 0,
|
||||
"update_dir": null
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"authority": "/data/digital-drosophila/experiments/phase4aq-conditioning-execution/authorities/performance--natural-light-fresh.epoch.json",
|
||||
"authority_sha256": "785e3d26d06b47efe7f054883d38fe2e13711195359bf9f4b03aa88887fbfb37",
|
||||
"chain_sha256": null,
|
||||
"output": "/tmp/malecns-cpu-residency-woqIQa/updates/01-N-resident",
|
||||
"sequence": 1,
|
||||
"update_dir": null
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"authority": "/data/digital-drosophila/experiments/phase4aq-conditioning-execution/authorities/mechanical--fresh-parent.epoch.json",
|
||||
"authority_sha256": "4616a42c255ab839346368aa0e5e4306bb3878e55fcc95b176f058b1993c9b0c",
|
||||
"chain_sha256": null,
|
||||
"output": "/tmp/malecns-cpu-residency-woqIQa/updates/02-M-resident",
|
||||
"sequence": 2,
|
||||
"update_dir": null
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"authority": "/tmp/malecns-cpu-residency-woqIQa/inputs/N_D0.authority.json",
|
||||
"authority_sha256": "4a7ee78ca0671efa0cb5203f7ba405ae3a53b3e23ebfcb8bf52887ce20c0f40b",
|
||||
"chain_sha256": null,
|
||||
"output": "/tmp/malecns-cpu-residency-woqIQa/updates/03-N_D0-resident",
|
||||
"sequence": 3,
|
||||
"update_dir": null
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user